我有以下coredata实体:
@interface Car (CoreDataProperties)
@property (nullable, nonatomic, retain) NSSet<Part *> *parts;
@end
@interface Part (CoreDataProperties)
@property (nullable, nonatomic, retain) Car *car;
@end
这是汽车和零件之间的一对多关系。在我的一个视图控制器中,我显示了包含所有部件的汽车视图。我想听听汽车各部分的变化。
我认为这对KVO来说很容易。
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.car addObserver:self forKeyPath:@"parts" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil];
}
然后:
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([@"parts" isEqualToString:keyPath]) {
// do what I need to do with new parts
}
}
然而,当我从服务器提取更改以更新汽车零件时,即使我没有更改任何零件,我也会收到observeValueForKeyPath方法的意外回调。
希望使用KVO,但也许使用coredata对象它不是一个好主意。我做错了什么或者我应该使用替代方案吗?
如果我不应该使用KVO,我相信我的其他选择是: 1.听取MOC的变化。这不是很好,因为我真的不知道对象上发生了什么变化。 2.在带有谓词的部件上实现一个FetchedResultsController,只找到我感兴趣的汽车。看起来有点矫枉过正,但我想这会给我我需要的东西。
答案 0 :(得分:3)
NSFetchedResultsController
是观察某些数据子集更改的首选方法。
对于单个对象,您可以观察NSManagedObjectContext
中的更改。
订阅NSManagedObjectContextObjectsDidChangeNotification
:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(contextDidChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:context];
当通知到达时,处理其userInfo
:
- (void)contextDidChange:(NSNotification *)notification
{
NSManagedObjectContext *context = notification.object;
NSDictionary *userInfo = notification.userInfo;
NSArray *invalidatedAll = userInfo[NSInvalidatedAllObjectsKey];
NSSet *invalidated = userInfo[NSInvalidatedObjectsKey];
NSSet *deleted = userInfo[NSDeletedObjectsKey];
NSSet *updated = userInfo[NSUpdatedObjectsKey];
NSSet *refreshed = userInfo[NSRefreshedObjectsKey];
// context reset
if (invalidatedAll) {
// probably you better have to dismiss your VC here.
return;
}
// invalidated
if ([invalidated containsObject:self.car]) {
// it make sense to dismiss here too.
return;
}
// deleted
if ([deleted containsObject:self.car]) {
// and here.
return;
}
// refreshed
if ([refreshed containsObject:self.car]) {
// update your interface.
return;
}
// updated
if ([updated containsObject:self.car]) {
// update your interface.
return;
}
}
要在相关Car
更新时收到有关Parts
对象的通知,请参阅此answer。
您可以从changedValues属性获取已更改属性的列表。
不要忘记取消订阅:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:NSManagedObjectContextObjectsDidChangeNotification
object:context];
}
<强>更新强>
这是以UIViewController
类别实施的概念:
BTDependentVC