ARC切換及開發注意事項

ARC切換及開發注意事項

ARC介紹


Automatic Reference Counting (ARC) 是一個編譯期的技術,利用此技術可以簡化Objective-C編程在內存管理方面的工作量。由開發人員來維護iOS對象的引用計數。不僅要求開發人員瞭解iOS的內存管理細節,更要求熟知並恪守計數管理規則。自動內存管理能夠有效提高開發人員的工作效率,同時減少手動管理帶來的人爲錯誤(野指針和泄露往往難以定位並且影響嚴重)。

ARC : ■ Easier to learn ■ More productive ■ Easier to maintain ■ Safer and more stable

ARC切換常見問題

1、iOS版本兼容

ARC is supported in Xcode 4.2 for OS X v10.6 and v10.7 (64-bit applications) 
and for iOS 4 and iOS 5.
Weak references are not supported in OS X v10.6 and iOS 4.

在iOS引入Weak references前,大多數項目會藉助開源代碼實現弱引用(如MAZeroingWeakRef)功能。同樣藉助開源項目 PLWeakCompatibility 我們可以在iOS4上使用Weak references。

PLWeakCompatibility is a set of stubs that implement the Objective-C runtime 
functions the compiler uses to make __weak work. It automatically calls through
to the real runtime functions if they're present (i.e. your app is running on 
iOS5+ or Mac OS X 10.7+) and uses its own implementation if they're not.By 
default, PLWeakCompatibility uses MAZeroingWeakRef to handle __weak if 
MAZeroingWeakRef is present. If not, it uses its own, less sophisticated, 
internal implementation.

2、第三方庫對ARC的支持

項目往往會關聯引用第三方庫而這些項目並不全支持ARC。

  • 不支持ARC的項目通過如下設置關閉ARC:Build Setting => Apple LLVM compiler 3.0-Code Generation => Objective-C automatic Reference Counting = NO
  • 不支持ARC的源文件通過如下設置關閉ARC:Build Phases => Compile Sources => Compiler Flags = -fno-objc-arc

3、性能及穩定性

有別於.Net/Java的全自動的垃圾回收機制,本質上仍然手動內存管理方式。ARC在編譯期間爲每個Objective-C指針變量添加合適的retain, release, autorelease等函數,保存每個變量的生存週期控制在合理的範圍內,以期實現代碼上的自動內存管理。








項目切換ARC問題

1、工作量

由於項目一直處於快速迭代狀態,沒有剩餘工作量可以投入切換工作,而且切換本身的工作量要高於前期的預估。雖然Xcode提供ARC自動轉換工具,但實際使用差強人意。手動一次性切換工作量太大並且切換後不易回滾。由於切換ARC涉及部分底層邏輯的改動,切換完成後需要回歸測試。

2、學習成本

項目開發人員習慣於非ARC下的開發,不瞭解ARC下的開發注意事項,可能影響開發效率及程序穩定性。需要學習瞭解ARC的原理以及使用注意事項。

3、項目發佈

切換後要保證程序的完整性以及穩定性,保證項目的按時發佈。這需要預留迴歸測試時間以及簡易的回滾機制。

項目切換ARC操作

  • 集成ARC-Safe Memory Management,在新增代碼中使用新的內存管理調用(Makes your code both ARC and non-ARC compatible!)
  • 已有的代碼則藉助Xcode的替換工具,使用正則表達式進行匹配、替換。
  • Objective-C and Core Foundation對象轉換修改。
  • 對不支持ARC的第三方庫及文件關閉ARC功能。
  • 全部替換完成後開啓工程ARC,編譯修復剩餘問題。
  • 修改存在自管理內存對象相關邏輯(ITTDataRequest)。
  • 觀察程序穩定性,測試修復存在的內存泄露以及循環引用。
  • 逐步清除相關內存管理宏定義的調用。

在項目提測前完成ARC切換,開發結束後一併提測。安排測試員做迴歸和穩定性測試,保證測試充分。

ARC開發注意事項

  • Forget about using retain, release, retainCount, and autorelease. 

  • Forget about using NSAllocateObject and NSDeallocateObject.

  • Follow the naming rule for methods related to object creation.
When an object is returned by certain methods, where the name begins with one of 
the list(alloc,new,copy,mutableCopy), the caller has ownership of the object. 
This rule is still applicable with ARC.
- (id) method __attribute((ns_returns_retained));      // return as retain +1, init,new,alloc,copy,mutablecopy default are this  
- (id) method __attribute((ns_returns_not_retained));  // just return
- (id) method __attribute((ns_returns_autoreleased));  // return as autorlease,  except default, are this 
- (void)initMethod __attribute__((objc_method_family(none))); 
  • Forget about calling dealloc explicitly.
You can’t call [super dealloc] explicitly. It is just done automatically by ARC.
  • Forget about using Zone (NSZone).
  • Object type variables can’t be members of struct or union in C language. 
  • ‘id’ and ‘void*’ have to be cast explicitly. 
  • Use @autoreleasepool instead of NSAutoreleasePool. 

Toll-Free Bridge

  • __bridge_transfer:用於將CF對象的管理權移至NSObject層由ARC負責。
  • __bridge_retained:用於將一個NSObject對象轉換成CF對象,並且引用計數加一。在CF層用完這個CF對象後,就需要使用CFRelease()釋放該對象。
  • __bridge:Just for assignment
to convert an object between Objective-C and Core Foundation
CFTypeRef CFBridgingRetain(id X) {
return (__bridge_retained CFTypeRef)X;
}
id CFBridgingRelease(CFTypeRef X) {
return (__bridge_transfer id)X;
}

所有權修飾符





PS:xib控件關聯非最外層的View,使用weak屬性聲明。

詳細的原理及技術細節可以查看:《Pro.Multithreading.and.Memory.Management.for.iOS.and.OS.X》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章