![](/img/trans.png)
[英]How to make NSManagedObject NSString properties be with “copy” instead of “retain”?
[英]NSString @property, using copy instead of retain
我正在查看 Apple 的示例應用程序 EditableDetailView,並注意到在他們的一個控制器中,他們正在使用(非原子,副本)設置 NSString 屬性的實例。 什么時候會使用副本而不是保留? 這樣他們就可以在不影響現有數據的情況下制作唯一的副本嗎?
是的,它可以在不影響現有數據的情況下制作唯一副本。 合成的 setter 基本上如下所示:
// For @synthesize(nonatomic, retain) foo:
- (void) setFoo(NSFoo *theFoo)
{
[theFoo retain]; // retain new value
[foo release]; // release old value, if any
foo = theFoo; // assign new value
}
// For @synthesize(nonatomic, copy) foo:
- (void) setFoo(NSFoo *theFoo)
{
NSFoo* newFoo = [theFoo copy]; // make copy
[foo release]; // release old value, if any
foo = newFoo; // assign new value
}
注意這里的操作順序很重要——新值必須在舊值被釋放之前保留/復制,以防自賦值。 如果您先釋放然后將屬性分配給自身,則可能會意外釋放該值。 另請注意,如果舊值為nil
,則可以向其發送release
消息,因為明確允許向nil
object 發送消息並且什么也不做。
選擇保留還是復制只是決定了對象的屬性是否與您設置的值相同。 考慮以下代碼:
// suppose the 'foo' property is declared 'retain' and the 'bar' property is
// declared 'copy'
NSFoo *foo = ...;
NSBar *bar = ...;
someObject.foo = foo;
someObject.bar = bar;
[foo changeInternalState]; // someObject.foo also changes, since it's the same object
[bar changeInternalState]; // someObject.bar does NOT change, since it's a copy
請記住,有一個 NS可變字符串。 能夠改變其他一些 object 擁有的字符串的內容(例如,通過刪除其一半的字符)會非常糟糕,特別是如果您沒有意識到您正在影響另一個 object。 因此,最好讓其他 object 自己制作副本。
你可能會說“好吧,我為什么不在分配字符串之前復制它呢?”。 也許 object 想要一個可變字符串,而你的字符串是不可變的。 如果必須先復制字符串,則必須在其文檔或 header 中查找所需的字符串類型,然后(每次)進行正確的復制。 這樣,您只需說other.string = myString
,它就會生成它想要的任何類型的副本——您不必擔心它。
(出於某種原因,這篇文章出現在我試圖回答的后續問題之上)回復:
你的意思是我必須在發布'foo'之前復制'foo' object?但是如果我在復制'foo'之前釋放'foo'會有什么問題?因為它們是兩個不同的object我不明白為什么釋放一個影響另一個!!!!
大多數時候,你是對的。 事實上,如果它們是兩個獨立的對象,那就沒關系了。 問題在於您可能將相同的 object 分配回自身。 如果你說
[myObject setFoo: moof];
[myObject setFoo: moof];
然后你第二次這樣做,你會在復制之前釋放 moof。 在此期間,如果 moof 的保留計數變為零,則可能會刪除 moof,並且在接下來的步驟中您將沒有任何內容可復制。 Foo 現在為零。
這有可能發生嗎? 可能比你想象的要多。 例如,有時用戶可能會點擊兩次“更新”按鈕。
我希望這是可以理解和有幫助的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.