我有一个与自身具有一对一关系的托管对象。这方面的一个例子可能是一个人对象可以链接到另一个人来代表一个婚姻。
如果人员的属性之一是地址并且它已针对一个人进行了更改,我将如何遵循这种关系并确保它已针对链接的人员对象进行了更改。
最初我考虑在 setter 中执行此操作,即 setAddress,但我很快意识到这会导致两个对象之间的无限递归。
什么是这类问题的优雅解决方案?
我有一个与自身具有一对一关系的托管对象。这方面的一个例子可能是一个人对象可以链接到另一个人来代表一个婚姻。
如果人员的属性之一是地址并且它已针对一个人进行了更改,我将如何遵循这种关系并确保它已针对链接的人员对象进行了更改。
最初我考虑在 setter 中执行此操作,即 setAddress,但我很快意识到这会导致两个对象之间的无限递归。
什么是这类问题的优雅解决方案?
您仍然可以在设置器中执行此操作,但只需检查目标值是否已经是您要设置的值,从设置器返回,没有任何无限循环。
你可以尝试类似的东西
- (void)setAddress:(NSString *)address
{
// common setter here
// then set your relationship's address
if (![self.personRelationship.address isEqual:address]) {
self.personRelationship.address = address;
}
}
1. 步骤
如果要覆盖 CoreData 中的设置器,则应遵循此处的文档:
关键是使用示例中的“原始”访问器:
- (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"];
}
根据您的描述,我会将地址移动到Address
与Person
. 建立关系,使每个人都有一个地址,并且每个地址可以被多个人使用。
通过这样做,您只需在一个地方更改地址,然后对任何使用该地址的人立即生效。如果两个拥有相同地址的人以后需要有不同的地址,Address
请为他们创建一个新实体。