ARC淺談

ARC限定符:

  • __strong -- 不使用任何修飾符的情況下,默認是__strong。在ARC環境下,編譯器會自動爲__strong修飾的對象指針生成恰當的release代碼,比如出了對象所屬作用域,或者發生指針賦值時。
  • __weak -- 使用__weak修飾符,編譯器(準確說是Runtime System)會記錄被修飾的指針,當指向對象被釋放時,將用__weak修飾的指針全部置爲nil。如果在非ARC環境下,假設a.delegate = b,通常delegate屬性爲assign,如果b被釋放了,a繼續用delegate指針訪問,有可能導致程序崩潰。這時候可以模擬__weak特性,讓b記錄下a.delegate指針,在dealloc時將其置爲nil。使用__weak指針,也可以消除循環引用
  • __unsafe__unretained -- 與__weak的差別就在於對象被釋放後,不會將指針置爲nil,所以最好是使用__weak,比較安全。通常爲了支持iOS 4或者OS X 雪豹才使用__unsafe__unretained。
  • __autoreleasing -- 顧名思義,該修飾符是將對象指針向自動釋放池註冊。在ARC環境下,可以使用@autoreleasepool {} 快速建立自動釋放池,並且編譯器會關注函數返回值,在需要時爲其進行註冊。比如 + (id)array { return [[NSMutableArray alloc] init]; },按理說出了作用域,對象會被釋放,但這裏編譯器會將該對象註冊到自動釋放池中。比如爲了安全使用__weak指針,編譯器也會自動將對象註冊到自動釋放池中。有一點不同的是,無修飾符的對象指針默認是__strong,而無修飾符的id指針(或者是對象指針的指針)則默認爲__autoreleasing。
ARC規則:
  • 不能調用retain、release、retainCount和autorelease也不能通過selector偷偷地調用它們: 禁止使用@selector(retain)和@selector(release)。所以記住上面那四個修飾符就好。
  • 忘掉NSAllocateObject和NSDeallocateObject
  • 創建對象的方法需要遵循一定的命名規則。以alloc、new、copy、mutableCopy開頭的函數表示調用者對被創建的對象擁有所有權,以init開頭的函數表示對對象進行初始化。這些函數需要是實例方法(而非類方法),並且返回一個對象。
  • 不要顯示調用dealloc。比如在dealloc函數中不要加[super dealloc],否則會有錯誤“ARC forbids explicit message send of 'dealloc' ”。不過,如果你需要釋放實例變量以外的資源,還是可以創建自定義的dealloc方法。但在這個方法裏,不要調用[super dealloc]。因爲ARC會幫你調。
  • 使用@autoreleasepool代替NSAutoreleasePool
  • 忘掉NSZone。關於NSZone,這裏有一份詳細文檔。
  • 對象類型變量不能作爲C語言中結構體(struct)或共用體(union)的成員
  • id和void *必須顯示轉換。這裏涉及到三個關鍵字:__bridge、__bridge_retained和__bridge_transfer,比如void *p = (__bridge void *)obj。三個關鍵字分別表示沒有所有權轉移的類型轉換、前後都擁有所有權的類型轉換以及所有權轉移(交接)的類型轉換。
ARC實現:
  • __strong -- 編譯器會幫我們在變量出作用域時添加release動作,如果該變量是函數返回值,增添加到自動釋放池中。
  • __weak -- 編譯器和Runtime System維護一張weak表,在給一個__weak指針賦值時,會將指針地址和指向對象作爲key-value註冊到表中。當指向對象被釋放時,搜索表將指針置爲nil,並移除該表項。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章