将属性更新级联到相关的托管对象

时间:2013-03-13 10:23:18

标签: objective-c core-data nsmanagedobject

我有一个与自身具有一对一关系的托管对象。这方面的一个例子可能是人物可以与另一个人联系以代表婚姻。

如果此人的某个属性是地址并且某个人的属性已更改,我将如何关注该关系,并确保已为链接的人对象更改该关系。

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

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

3 个答案:

答案 0 :(得分:1)

您仍然可以在设置器中执行此操作,但只需检查,如果目标值已经是您要设置的值,则从setter返回,没有任何无限循环。

您可以尝试类似

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

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

答案 1 :(得分:1)

<强> 1。步骤

如果要覆盖CoreData中的setter,请遵循以下文档:

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"];
}

答案 2 :(得分:1)

根据您的说明,我会将地址移动到与Address有关系的单独实体Person中。建立关系,以便每个人都有一个地址,每个地址可以由多个人使用。

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