使用ARC時須要遵循的規則


若是想用ARC,必須服從一些新規則

1. 對象的Alloc/Init程序員

建立對象的方法跟之前同樣,但你必定不能調用retain/release/autorelease/retainCount。也不能經過selector偷偷地調用它們: 禁止使用@selector(retain)和@selector(release)。函數

2. dealloc方法工具

ARC爲自動爲你調用,必定不能直接調用dealloc。不過,若是你須要釋放實例變量之外的資源,仍是能夠建立自定義的dealloc方法。但在這個方法裏,不要調用[super dealloc]。由於ARC會幫你調。spa

3. 聲明的屬性指針

在ARC以前,咱們是用@property指令中的assign/retain/copy參數來告訴編譯器,如何管理這些屬性的內存。用了ARC以後,這些參數就做廢了,改用weak/strong這兩個參數。code

4. C結構中的對象指針orm

一樣禁止使用。文檔裏建議不要把它們放在結構了,改放到類裏去。不然ARC就不認識它們了。可能會出現一些移植上的問題。不過,ARC是能夠以文件爲單位來關閉的。參考下文的「引入不兼容ARC的代碼」。對象

5. id與void*之間的臨時互轉內存

當咱們在Core Foundation的C函數和Foundation Kit的Objective-C方法間傳遞對象時,經常須要進行id和void*兩個類型的互轉。叫作免費橋接(Toll Free Bridging)。資源

若是使用ARC,必須在CF對象進入和脫離ARC的控制時,用提示/限定符來告知編譯器。限定符有__bridge、__bridge_retain和__bridge_transfer。另外,仍須要用CFRetain和CFRelease來管理Core Foundation的對象。

這一塊已經比較高深了,若是你不清楚CF對象是什麼,也不須要太煩惱。


6. 以@autoreleasepool代替NSAutoReleasePool

兼容ARC的代碼不能再使用NSAutoReleasePool對象,而要改用@autoreleasepool{ }塊。

7. 其它

基於Zone的內存已經沒了(在運行時裏也沒了)。不能再使用NSAllocateObject和NSDeallocateObject。


ARC限定符 - 聲明的屬性

身爲程序員,習慣於作出一些決定,例如把某個量聲明爲變量仍是常量、本地仍是全局,等等。所以,在這裏,咱們也要決定某個屬性與其它屬性的關係。咱們用strong/weak來把這一關係告訴編譯器。

強引用

強引用是對某對象的引用,而且能阻止它被回收。換句話說,強引用建立了一個全部關係。在ARC以前,咱們這麼寫:

// Non-ARC Compliant Declaration
@property(retain) NSObject *obj;

在ARC下,咱們須要這麼寫,以確保當前實例得到被引用對象的全部權(主人不被回收,它也不能被回收)。

// ARC Compliant Declaration
@property(strong) NSObject *obj;

弱引用

弱引用是對某對象的引用,但不能阻止它被回收。換句話說,弱引用並不會建立全部關係。在ARC以前,咱們這麼寫:

// Non-ARC Compliant Declaration
@property(assign) NSObject *parentObj;

在ARC下,咱們須要這麼寫,以確保當前實例沒有得到被引用對象的全部權(通常來講,子對象不該該擁有父對象,這時能夠用弱引用)。

// ARC Compliant Declaration
@property(weak) NSObject *parentObj;


ARC限定符 - 常規變量

上一節是說明如何管理屬性。對於常規變量,則有:

__strong
__weak
__unsafe
_unretained
__autoreleasing

通常來講,咱們不太須要使用上面這些限定符。在使用移植工具的時候可能會看到那麼幾個,但新工程基本上不須要。

__strong: 默認限定符,不須要顯式指定。表示任何用alloc/init建立的對象在當前範圍的生命期內得以保留。「當前範圍」是指變量聲明語句所在的兩個大括號之間(方法、循環、塊,等等)。

__weak: 表示對象能夠隨時被摧毀。只有當它被其它對象強引用時纔有用。__weak變量在摧毀時,被設爲nil。

__unsafe_unretained: 與__weak相似,但在摧毀時,不設爲nil,保留原值(再也不指向有效的東西)。

__autoreleasing: 不要與autorelease搞混,它用於經過引用傳遞對象,好比,經過引用傳遞NSError對象: [myObject performOperationWithError: ]。

相關文章
相關標籤/搜索