理解ARC在Objective-C中的应用
原文:http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/
名詞解釋:Automatic Reference Counting(ARC):自動引用計數
ARC在很大程度上消除了手動內存管理的負擔,同時省去了追查內存泄露和過度釋放對象引起的繁瑣操作。盡管ARC非常吸引人,但是不會讓你完全忽略內存管理。
下面的告示包含了ARC一些關鍵方面來幫助你快速建立和運行你的項目。
? ? What Has Changed?
ARC之前,你必須手動的retain/release/autorelease對象來確保對應的對象存在,當你需要操作這些對象時。如果忘記retain一個對象,或者多次釋放同一個對象,會導致應用內存泄露或者應用崩潰。
在Xcode4.3.2中,除了進行輸入時語法檢查,新的Apple LLVM編譯器將手動管理內存的負擔轉移給編譯器,內省你的代碼決定何時進行對象釋放。蘋果文檔描述ARC信息如下:“ARC is a compiler-level feature that simplifies the process of managing object lifetime(memory management) in Cacoa applications."
ARC減少了進行手動管理內存的瑣碎的時間,但是你仍然需要拿出一些精力來處理如何管理你的類中對其他對象的引用。
讓我們從頭開始吧。。。
Reference Counted Memory:Quick Review
iOS中手動管理引用計數內存的工作方式如下:當使用alloc/init(or other similar method)創建一個對象,返回被創建對象的的retainCount為1,意味著你已經擁有了對象的所有權。
[plain]? view plain copy
在分配初始化一個對象與釋放一個對象之間,你可以做你想做的操作,安全的對象不會被自動釋放,當需要的時候可以被操作。
同樣的,把一個對象添加到自動釋放池中,當需要的時候,你操作的對象將繼續有效 并且在將來的某個時刻不再被需要時,將被釋放。
[plain]? view plain copy
How Automatic Reference Counting Works
大部分iOS新手接觸引用計數內存時都會陷入困境。ARC是在預編譯階段為你的代碼添加retain/release/autorelease的。
這不是垃圾回收,引用計數內存沒有消失,被用自動化的方式化繁為簡。ARC聽起來好像有點后續考慮的意味,但是細想一下,在Objectie-C中有多少功能在編譯之前是通過預處理源文件的方式來實現的,ARC就是非常具有代表的課題。
當你使用ARC方式來編碼時,代碼格式如下:
[plain]? view plain copy
[plain]? view plain copy
下面的圖表(來自蘋果文檔)好像暗指有效代碼與retain/release的邏輯代碼一樣長。對于有Objective-C編碼經驗的人是不準確的,但是對于Objective-C的新人保守估計來看是這樣的。
Enabling ARC in Your Project
New Rule Enfored by ARC
為了能通過ARC的方式進行編譯,必須遵守一些規則。
1.alloc/init objects
像之前描述的,按照之前的方式創建對象,就不必再做retain/autorelease/retainCount操作。你不能間接的操作他們的selector:@selector(retain)和@selector(release)的操作將會被禁止。
2.dealloc methods
通常情況將會自動為你創建,你不必直接調用該方法。盡管你可以創建一個定制的dealloc方法來釋放資源而不是實例變量。當創建是定制的方法時,不要調用[super dealloc]方法。編譯器將會強行來為你做該操作。
3.declared properties
[plain]? view plain copy
ARC之前,我們告訴編譯器如何進行內存管理,使用assign/retain/copy參數的命令@property來聲明公共屬性。這些參數將不會在ARC中使用,我們會使用weak/strong參數來告訴編譯器如何來操作屬性。
4.object pointer in c structures
這是一個禁忌。文檔建議使用類而不是結構體的方式來實現,這種方式非常有益因為結構體對于ARC是未知的。結構體將會引起額外的遷移麻煩。盡管,ARC基于文件是無效的。參見下面的"including code that is not ARC compliant"
5.casual(邂逅) casting between id and void*
當操作Core Foundation's C庫與Foundation Kit's Objective-C庫的方法時,在id與void*數據類型之間將會進行頻繁的轉換。就像我們所知道的 Toll Free Bridging(點擊打開鏈接).
使用ARC你必須提供hints/qualifiers 來告訴編譯器當CF對象進入或者退出控制范圍來進行內存管理。這些標示符包括__bridge,__bridge_retain and __bridge_transfer.同時,你需要調用CFRetain和CFRelease 來進行內存管理 Core Foundation 對象。
這是一個非常高級的話題,如果你不知道CF Object,現在并不需要擔心什么。
6.@autoreleasepool instead NSAutoReleasePool
ARC編譯代碼不能使用NSAutoReleasePool,必須使用@autoreleasepool{}塊.任何一個ARC編譯或遷移的工程中的main.m文件是一個非常好的例子。
[plain]? view plain copy
基于內存的區域已經不存在啦(很明顯說的不是在程序運行的時候);你不能使用NSAllocateObject 或NSDeallocateObject.
ARC Qualifiers - Declared Properties
作為編程人員,我們通常會決定是否定義一些局部或全局的變量或常量等等。同樣,我們必須決定我們的和其他對象相關的屬性。我們使用strong/weak標示符來告知編譯器這些關系。
Strong References
一個對象的強引用會阻止被引用的對象被釋放掉。換句話來講,創建了一個所屬關系??紤]到之前的情況,你將會這樣來操作:
[plain]? view plain copy
[plain]? view plain copy
Weak References
一個對象的弱引用不能阻止被釋放掉。換句話來說,不能創建所有權擁有關系。
[plain]? view plain copy
ARC Qualifiers - Regular Variables
Variables Qualifiers
上面的例子描述了我們如何創建屬性并進行管理,我們擁有的普通變量如下:
[plain]? view plain copy
__strong 是默認的類型,不需要打印。這意味著使用alloc/init創建的任何對象在當前有效范圍內將保留整個生命周期。
__weak 指對象在任何時刻都能被銷毀。__weak變量被銷毀時,變量將被置為nil。
__unsafe_unretained很像__weak,但是當對象被釋放時,指針不會被置為nil,指針會被隨即賦值。
__autoreleasing,not to be confused with calling autorelease on an object before returning it from a method,this is used for passing objects by reference,for example when passing NSError objects by reference such as [myObject performOperationWithErro:@tmp];
Source:LLVM Clang Objective-C Automatic Reference Counting Documentation
NB:We have found @property declarations using 'retain' with ARC enabled(ie.instead of 'strong')do not cause compiler warnings and yield the same compiled result.This could change in future so stick to 'strong' fro clarify.
Migrating Existing Projects to ARC
Xcode 4.3.2提供了一個轉換工具將現存代碼遷移到ARC,不能自動遷移,需要手動轉換。
Including Code that is not ARC Compliant
...
Should I User ARC?
...
ARC Resources:
...
other iOS Resources
http://longweekendmobile.com/2010/07/28/resources-for-learning-iphone-programming/
總結
以上是生活随笔為你收集整理的理解ARC在Objective-C中的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JIRA 6.3.6 详细安装图解
- 下一篇: 进程间通信(总结)