[英]Inter-Model/NSManagedObject communication
我有两个NSManagedObject子类:Parent和Child。 Parent在OrderedSet中包含许多Child(ren)。 当孩子的状态发生变化时,我希望父母知道它。
如果我使用其他语言进行编程,我可能会使用事件,让父母监听来自每个孩子的事件,但是鉴于目标操作仅限于查看组件,所有Objective C都提供给我使用全局NSNotificationCenter。 我绝对不喜欢使用模型进入全局通知的想法(直接通过事件直接监听我的书中的确定),所以看来我唯一的选择是委托。 然而,在两个NSManagedObjects之间使用委托似乎是一个危险的想法,因为很难确保一方不会丢失对另一方的引用。
有没有人对我应该如何处理这个有任何建议?
另一种选择是键值观察。 设置如下:
const static void *kParentObservingChildSomePropertyContext = &kParentObservingChildSomePropertyContext;
[child addObserver: child.parent forKeyPath: @"someProperty" options: /*see below*/ context: kParentObservingChildSomePropertyContext];
存在奇怪的常量定义,因为每个观察上下文都应该是唯一的,这样你就不会踩到超类或子类观察上下文。 要查看需要设置的选项, 请参阅手册并与您的具体需求进行比较。 现在,只要您的子对象上的该属性发生更改,您的父级将会收到:
-(void)observeValueForKeyPath: (NSString *)path ofObject: (id)object change: (NSDictionary *)change context: (void *)context;
检查您是否具有正确的观察背景,然后处理更改。 如果您在此处获得不同的上下文,请将消息转发给super
。
当您完成观察路径时,您将父项删除为子项的观察者:
[child removeObserver: child.parent forKeyPath: @"someProperty" context: kParentObservingChildSomePropertyContext];
使用在-addObserver:forKeyPath:options:context
使用的相同上下文指针-addObserver:forKeyPath:options:context
以便删除正确的观察实例。
然而,在两个NSManagedObjects之间使用委托似乎是一个危险的想法,因为很难确保一方不会丢失对另一方的引用。
委派,观察和观察来自特定对象的通知都会遇到这个问题。 您需要确保您对通知感兴趣的生命周期与所涉及对象的生命周期相匹配,否则您可能很容易“泄漏”观察信息或 - 这更糟糕 - 将通知发送到过时的对象指针。 这些解决方案都不具备这一点,但在Delegate模式的情况下,您可以使用归零弱引用来确保当父对象消失时,子进程将不再尝试委托它。
我在视图控制器中选择一个字段来监视请求... [self addObserver:self forKeyPath:@“clientProgress.dateLastUpdated”options:0 context:nil];
我确保在相同的视图控制器中删除dealloc上的观察者(或者在ARC中的dealloc的任何传递)。 - (void)dealloc {[self removeObserver:self forKeyPath:@“clientProgress.dateLastUpdated”]; }
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqual:@"clientProgress.dateLastUpdated"]) {
// If this key path has changed, the browser needs to update its display.
NSError *error = nil;
if (![managedObjectContext save:&error]) {
UIAlertView *dialog = [[UIAlertView alloc] initWithTitle:@"Save Error" message:@"Error saving inserted record, contact Tech Support" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[dialog show];
[dialog release];
exit(-1); // Fail
}
if ( changeIsComingFromLibraryInsert ) {
}
[conditioningTableView reloadData];
}
// Essential to call super class implementation - NSArrayController relies heavily on KVO
//[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
最后,当我想调用观察者时,我只是更新日期... //通过设置修改日期和前面的ViewController强制保存,然后从调用视图控制器保存并重新加载//因为有一个观察者正在运行看这个关键值clientProgress.dateLastUpdated = [NSDate date];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.