2010-07-18 103 views
3

我終於明白我是否必須釋放一個對象,以及如何在一個簡單的應用程序中保留我的保留數儘可能低(通過知道對象是否返回額外的'保留'已經被調用或不)。所以NARC規則在這方面工作得很好。另一方面,我無法圍繞是否要retain(通常使用保留屬性)或僅僅是assign實例變量來包裝我的頭。那裏有什麼經驗法則嗎?我知道只有兩個:超越NARC:什麼時候保留,何時分配,什麼時候複製

  1. 如果我在我的班級中所做的實例(例如,在一個init),那麼我應該保留它,並在dealloc釋放。
  2. 代表得到分配,不保留

但我不明白的是我是否應該保留我從另一個實例傳遞的東西。我知道風險在於保留數減少到零,而我仍然拿着袋子(或者留下許多額外的袋子和記憶),但是......我應該如何組織我的應用程序以防止這種情況發生?

我見過一些related questions,但沒有一般。

當我在這裏:什麼已添加到UIWindowUIView,我沒有親自保留的東西呢?如果他們的超級視圖從所有超級視圖中刪除,「自然」保留的實例是否會被釋放?

回答

2

如何讓我保留計數儘可能低

我不明白這一點。是什麼讓你覺得你需要擔心保留數量呢?保留數是一個實現細節,忘記它。所有你需要擔心的是你是否擁有一個物體。

我不能籠絡我的頭是否保留(通常使用保留屬性)或只是分配實例變量。

幾乎在您分配實例變量時要保留或複製的所有情況。主要的例外是保留週期。有時候,你會發現自己處於對象A引用對象B,對象B引用對象A的情況。如果A保留B和B保留A,那麼不能依賴dealloc中釋放引用的正常模式他們走開。在這種情況下,通常將一個對象指定爲所有者,將另一個指定爲擁有者。擁有的對象將不會保留對所有者的引用。

一個這樣的例子將是一個樹結構,其中父節點具有對其子元素的引用,並且每個子元素都具有對其父元素的引用。如果每個孩子保留其父母,當申請與父母一起完成時,它不會消失,因爲它已被所有孩子保留。因此,家長參考被實施爲弱參考,這意味着孩子不保留其父母。

這是一個非常常見的模式,代表對象的所有者將其自身設置爲對象的委託。例如,表視圖的控制器通常也是表視圖的數據源和/或委託。如果表視圖保留委託,您將有一個保留週期(因爲控制器已保留該視圖)。這就是爲什麼會議「代表不被保留」的原因。

如果您想要引用的對象實現NSCopying,並且您擁有所有權時不需要更改,則應該明確複製。 Cocoa的一個例子是NSDictionary中元素的關鍵。如果字典中的密鑰要更改,那將是一場災難。所以NSDictionary複製它的密鑰。

我知道,風險是保留計數下降到零,我左手拿着袋子(或左手拿着很多額外的包裝袋和內存),但是...我應該怎麼安排我的應用程序,使這不會發生?

簡單:按照Cocoa memory management rules。如果在你引用它的時候有什麼東西消失了,那麼你並不擁有這些東西。如果你需要一些東西來維持比當前方法的範圍更長的時間,你應該保留它。

+0

感謝分享,很高興聽到另一個版本的相同的東西,只是爲了更好地理解它。我不擔心保留數量,但是至少在記住它們的時候,很難理解爲什麼我會擔心釋放很多。這是爲了保持較低的保留數=較低的內存佔用。 – 2010-07-19 20:19:37

10

對於類類型的對象要:

  • retain每默認
  • copy如果類是由一個可變/不可變類集羣
  • assign,如果你需要weak references

至於清理,所有retaincopy屬性需要是released

如果我在我的類中創建了實例(例如,在init中),那麼我應該保留它並在dealloc中釋放它。

的問題不在於是否有人在你的類的方法創建的,但無論你:

  • 希望有一個強有力參考實例
  • 已經擁有了它

如果您還沒有擁有它並希望獲得強有力的參考,請保留 - 傳遞到您的方法中的實例也是如此。無論您是通過設置者明確還是隱含保留都無關緊要。

+0

好東西+1。我認爲這個鏈接也是一個很好的鏈接。 – 2010-07-19 00:44:05

+0

「保留每個默認值」?你的意思是保留是默認屬性?如果是這樣,你錯了。由於assign是默認的。 – 2010-08-27 07:38:44

+0

@comp:「*你想保留每個默認值」 - 即你想使用'retain'屬性,除了[...]時。 – 2010-08-27 09:54:53

相關問題