在前面分析了nomantic、copy、retain等屬性之後,在教新的XCode版本中,我們又經常會看到__unsafe_unretain、__strong、__weak、__autoreleasing這四種屬性,那麼他們有什麼用呢?
__unsafe_unretain、__strong、__weak、__autoreleasing是出現在 LLVM 編譯器 3.0版本之後。而__unsafe_unretain、__strong、__autoreleasing可以在不使用ARC(自動參考計數)可用。在ARC下,預設的指標都是__strong屬性。這意味著一個對象賦值給另外一個指標,那麼只要指標參考了該對象,該對象就會一直保持。這對於大部分對象都實用,但是這可能會導致retain cycle。例如,你擁有一個對象包含了另外了一個執行個體變數對象,但是第二個對象又把前一個對象作為它的委託,那麼這兩個對象將不會被釋放。
因為上面的原因,所以才有了__unsafe_unretain和__weak限定符存在。他們通常用來修飾delegate,即定義一個delegate的屬性時,使用__unsafe_unretain和__weak來修飾,然後通過使用__unsafe_unretain和__weak來單獨標記執行個體變數。這意味著delegate執行個體變數將仍然能夠指向第一個對象,但是它不會導致保留第一個對象,因此打破了retain cycle,而能夠釋放兩個對象
除了delegate,__unsafe_unretain和__weak修飾符也還能避免你的代碼出現retain cycle。Leaks instrument現在包含了一個cycle視圖,能夠發現你的應用中的retain cycle,並映像顯示出來。
__unsafe_unretain和__weak都能避免retain cycle,但是他們也有一些細微的不同。對於__weak,當釋放指標指向的對象時,該對象的指標將轉換為nil,這是比較安全的行為。而__unsafe_unretain,正如其名稱隱藏的含義,儘管釋放指標指向的對象時,該指標將繼續指向原來的記憶體。這將會導致應用crash,所以是unsafe。
為什麼我們仍要使用__unsafe_unretain呢?這是因為__weak直到iOS5.0以及lion之後才出現。
而__autoreleasing 的英文解釋為:to denote arguments that are passed by reference (id *) and are autoreleased on return,即主要是在引用傳參時使用。
最後需要注意的一點是:cocoa設定了一個規則,即父物件建立子物件的強引用,而子物件只對父物件建立弱引用。
而使用弱引用時需要注意,當你發訊息給一個被dealloc的弱引用對象時,你的程式會崩毀。因此,必須細緻地判斷對象是否有效。多數情況下,被弱引用地對象是知道其他對象對它的弱引用的,所以當它自己dealloc時,需要通知對它弱引用的其他對象。