2013-03-13 54 views
1

我有一个托管对象与其自身有一对一的关系。这方面的一个例子可能是一个人的对象可以与另一个人联系起来代表婚姻。将属性更新级联到相关的管理对象

如果该人的其中一个属性是地址,并且对于一个人而言已被更改,那么我将如何遵循该关系并确保它已针对链接人物对象进行更改。

最初我想在setter中这样做,即setAddress,但我很快意识到这会导致两个对象之间的无限递归。

什么是这种类型的问题的优雅解决方案?

回答

1

你仍然可以在setter中做到这一点,但只要检查目标值是否已经是你想设置的目标值,就从setter返回,没有任何无限循环。

你可以尝试像

- (void)setAddress:(NSString *)address 
{ 
    // common setter here 

    // then set your relationship's address 
    if (![self.personRelationship.address isEqual:address]) { 
     self.personRelationship.address = address; 
    } 
} 
+0

感谢您的回复,请提供一个简单的例子吗? – olly 2013-03-13 10:39:32

+0

你需要在你的setter中加入'-willChangeValueForKey:'和'-didChangeValueForKey:',而通用setter应该是'setPrimitiveAddress:'。看deepflame的答案。 – paulmelnikow 2013-03-13 16:38:55

+0

完美地工作,谢谢 – olly 2013-03-13 21:59:08

1

第1步

如果你想覆盖CoreData你应该遵循此文件的制定者:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html#//apple_ref/doc/uid/TP40002154-SW14

关键在于使用“原始”访问器,如示例中所示:

- (void)setAddress:(NSString *)newAddress 
{ 
    [self willChangeValueForKey:@"address"]; 
    [self setPrimitiveAddress:newAddress]; 
    [self didChangeValueForKey:@"address"]; 
} 

然后,您将不会尝试设置该属性的无限循环。

2步

它应用到你可以设置对方的地址和地址的问题。

该代码将变为

- (void)setAddress:(NSString *)newAddress 
{ 
    [self willChangeValueForKey:@"address"]; 
    [self setPrimitiveAddress:newAddress]; 
    [self didChangeValueForKey:@"address"]; 

    [self.partner willChangeValueForKey:@"address"]; 
    [self.partner setPrimitiveAddress:newAddress]; 
    [self.partner didChangeValueForKey:@"address"]; 
} 

替代的NOA建议:

- (void)setAddress:(NSString *)newAddress 
{ 
    [self willChangeValueForKey:@"address"]; 
    [self setPrimitiveAddress:newAddress]; 
    if (![self.partner.address isEqual:newAddress]) 
     [self.partner setAddress:newAddress]; 
    [self didChangeValueForKey:@"address"]; 
} 
+0

良好的建议重新KVO方法,但我不明白你的代码的其余部分与OP有关更新地址的问题有关。核心数据关系会自动更新它们的逆向,所以我不知道这些代码是否有必要或甚至会起作用。对自己以外的东西调用willChangeValueForKey和setPrimitive ......对我来说似乎也是诡异的。 – paulmelnikow 2013-03-13 16:34:49

+0

好点。让我稍后重新修改并更新代码。当我回答这个问题时,似乎已经太迟了。 – deepflame 2013-03-13 17:27:28

+0

这是现在更新。再次感谢评论@noa – deepflame 2013-03-14 01:53:09

1

根据您的描述我的地址移到该有Person关系的独立实体Address。建立关系,以便每个人都有一个地址,每个地址可以被多个人使用。

通过这样做,您只需要在一个地方更改地址,然后立即对任何使用该地址的人员生效。如果稍后具有相同地址的两个人需要具有不同的地址,则为他们创建一个新的Address实体。

+0

更优雅的解决方案! – 2013-03-13 19:52:41