簡體   English   中英

NSString @property,使用復制而不是保留

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM