Pages

Thursday, March 1, 2012

Automatic Reference Counting in Objective-C and Xcode

Automatic Reference Counting
Automatic Reference Counting (ARC) 可以幫我們 Developer 程式開發上移除大量的記憶體管理,如此一來幫我們降低 Bugs,不論是 leaking 或是重複釋放物件 (objects)。雖然 ARC 擁有這樣棒的功能,我們還是有很多細節要處理。

在 Apple 的文件對於 ARC 解釋是:
Automatic Reference Counting (ARC) is a compiler-level feature that simplifies the process of managing object lifetimes (memory management) in Cocoa applications.

在還沒有 ARC 以前我們程式上要寫 retain, release 和 autorelease 來確保我們有適當的使用記憶體空間,當不使用了有正常的釋放。更不要說呼叫到一個需要 retain 的物件造成 App crash 或者重複忘記 release 造成 App 變成 memory leak。從 Xcode 4.2 開始,新的 Apple LLVM compiler 編譯器讓這些耗功的地方可以在編譯階段獲得處理,在編譯階段根據 Code 來處理 Release 物件。

手動管理 Reference count
在我們手動管理記憶體 reference count ,程式上會需要 alloc 和 init,這時物件會回傳 retain count,因此在結束後必須要 release 它。



如果不知道呼叫者何時不需要使用,要加上 autorelease。


 
Automatic Reference Counting
有個概念很重要,這不是我們在別的程式語言像是 Java 所提到 Garbage Collection,因為 Garbage Collection 是在 Run-time 期間處理的。這些 Reference Counting 依舊存在,只是在編譯階段幫我們處理掉,讓我們不用再煩惱釋放狀況了。使用了 Automatic Reference Counting 之後,我們則需要寫成這樣。


ARC 的使用方法
  • Alloc, init objects - 當在宣告一個物件時候使用 alloc 和 init,但是千萬不要加上任何的 retain, release 或者 autorelease。當然也不要用任何 Selector 去呼叫 @selector(retain) 或者 @selector(release)。 
  • Dealloc - 就不要在寫 dealloc 了。ARC 會幫我們做到,除非我們想要做些特別處理,但是使用了 dealloc 就不要再呼叫 [super dealloc] 了,這部分也是會幫忙做到。
  • 宣告 Properties - 在還沒有使用 ARC 以前,我們宣告要用到 assign, retain 或者 copy 這些處理記憶體的寫法,這些在 ARC 裡面不會使用了。取而代之的是 weak 和 strong 來告訴編譯器我們在程式上是如何使用的。
  • 使用 Variables - 要使用 strong, weak, unsafe_unretained, autoreleasing。

Strong 與 Weak
  • Strong 的參考上是參考到一個物件一直到當該物件被 deallocted,也就是會幫我們建立出彼此的關聯性,建立彼此的擁有權生命週期。 
  • Weak 的參考上是一直對應到該物件,就算這個物件被 dealloc 了還是存在。所以它不會建立擁有權。
  • _strong 是預設值,所以不打出來就是這樣的方式,建立了物件就會幫忙處理所有的 retained 和 released,自己內部這個物件使用。
  • _weak 代表這個物件可以隨時不見都沒有關係,如果對應到某個物件就算被 dealloc 它就會變成 nil 。
  • unsafe_unretained 這是跟 weak 一樣,但是當物件被 dealloc 不會將指標變成 nil。只是會變成指到無效的物件。
  • _autoreleasing 這會指引到該物件並且建立 autorelease 關係。

在 Project 裡面開啟 ARC
要打開 ARC 只要在 Xcode project’s build setting 找到 reference counting 將它設定為 YES,那麼就會幫我們在編譯階段加上 -fobjc-arc 編譯 flag 來處理。

將既有的 Projects 轉換成為 ARC
打開不是 non-ARC 的 Project 在 Edit -> Refactor -> Convert to Objects-C ARC。會出現一個勾選確認的表單,再點選後程式上會將非 ARC 程式碼轉成 ARC 。如果這過程有些狀況在視情況處理。好了之後可以到 build setting 裡面找 reference counting 是否改為 YES 了。

引用了 Code 不是 ARC 建立出來的
我們還是可以將 ARC 與 non-ARC 的程式碼並存使用,在 Xcode Project 找到 Target 裡面的 Build Phases tab ,展開 Compile Sources 區域將這些程式碼檔案拍開到 ARC 之外,在後面的 key 地方一一加上 -fno-objc-arc ,目前我還找不到可以一次改多個檔案,所以只好一個一個加。因此當加了這些編譯註記,那麼就會被排外。

最後
如果新的 Objective-C 學習者,來使用 ARC 會很適合,這可以不用在初期寫程式就傷腦筋 reference count 的管理,而如果像是已經寫 Objective-C 一陣子了如果習慣這樣用法不使用也沒關係,目前為止還是有很多的 libraries 或是 Open Source Projects 還沒轉成 ARC。當然以效能上來說,有些參考數據已經顯示 ARC 可以讓 Project 跑起來更為快速,在 release 或是 autorelease 會用的非常恰當。ARC 的任務是選擇最優化、自動化的方式來幫程式碼加上這些管理。當然最根本程式上不論使用了 ARC 或者 non-ARC,寫 Code 的嚴謹還是最重要的。

No comments:

Post a Comment