我有一個託管對象與其自身有一對一的關係。這方面的一個例子可能是一個人的對象可以與另一個人聯繫起來代表婚姻。將屬性更新級聯到相關的管理對象
如果該人的其中一個屬性是地址,並且對於一個人而言已被更改,那麼我將如何遵循該關係並確保它已針對鏈接人物對象進行更改。
最初我想在setter中這樣做,即setAddress,但我很快意識到這會導致兩個對象之間的無限遞歸。
什麼是這種類型的問題的優雅解決方案?
我有一個託管對象與其自身有一對一的關係。這方面的一個例子可能是一個人的對象可以與另一個人聯繫起來代表婚姻。將屬性更新級聯到相關的管理對象
如果該人的其中一個屬性是地址,並且對於一個人而言已被更改,那麼我將如何遵循該關係並確保它已針對鏈接人物對象進行更改。
最初我想在setter中這樣做,即setAddress,但我很快意識到這會導致兩個對象之間的無限遞歸。
什麼是這種類型的問題的優雅解決方案?
你仍然可以在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;
}
}
第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"];
}
良好的建議重新KVO方法,但我不明白你的代碼的其餘部分與OP有關更新地址的問題有關。核心數據關係會自動更新它們的逆向,所以我不知道這些代碼是否有必要或甚至會起作用。對自己以外的東西調用willChangeValueForKey和setPrimitive ......對我來說似乎也是詭異的。 – paulmelnikow 2013-03-13 16:34:49
好點。讓我稍後重新修改並更新代碼。當我回答這個問題時,似乎已經太遲了。 – deepflame 2013-03-13 17:27:28
這是現在更新。再次感謝評論@noa – deepflame 2013-03-14 01:53:09
根據您的描述我的地址移到該有Person
關係的獨立實體Address
。建立關係,以便每個人都有一個地址,每個地址可以被多個人使用。
通過這樣做,您只需要在一個地方更改地址,然後立即對任何使用該地址的人員生效。如果稍後具有相同地址的兩個人需要具有不同的地址,則爲他們創建一個新的Address
實體。
更優雅的解決方案! – 2013-03-13 19:52:41
感謝您的回覆,請提供一個簡單的例子嗎? – olly 2013-03-13 10:39:32
你需要在你的setter中加入'-willChangeValueForKey:'和'-didChangeValueForKey:',而通用setter應該是'setPrimitiveAddress:'。看deepflame的答案。 – paulmelnikow 2013-03-13 16:38:55
完美地工作,謝謝 – olly 2013-03-13 21:59:08