另一种选择是键值观察。像这样设置它:
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
以便删除正确的观察实例。
然而,在两个 NSManagedObjects 之间使用委托似乎是一个危险的想法,因为很难确保一方不会失去对另一方的引用。
委托、观察和监视来自特定对象的通知都存在这个问题。您需要确保您对通知感兴趣的生命周期与所涉及对象的生命周期相匹配,否则您可能很容易“泄漏”观察信息,或者 - 更糟糕的是 - 将通知发送到陈旧的对象指针。这些解决方案都不能对此免疫,尽管在委托模式的情况下,您可以使用归零弱引用来确保当父对象消失时,子对象将不再尝试委托给它。