Effective Objective-C 2.0 閱讀筆記

weixin_33724059發表於2016-03-17

第五章 記憶體管理

1.ARC並不會呼叫retainrelease等方法,而是直接呼叫其底層C語言版本objc_retain等,所以ARC沒有普通的OC訊息派發機制。

2.如果setter方法像下面這樣寫,當新值和舊值相同時就程式就會崩潰。


-(void)setObject:(id)object{
    [_object release];
    _object=[object retain];
}

3.ARC中的命名規則:如果方法名以allocnewcopymutableCopy開頭,則返回物件歸呼叫者所有,否則返回的物件會自動釋放。

4.dealloc方法裡要釋放指向其他物件的引用,取消鍵值觀測(KVO)和NSNotificationCenter通知,不要在這裡執行非同步任務或應該在正常狀態下執行的任務,因為這是的物件已經處於正在回收狀態了。

5.ARC預設不生成安全處理異常的程式碼,設定-fobjc-arc-exceptions標誌後可以開啟,不過會導致應用程式變大,效率變低。

6.unsafe_unretainweak都可以用來消除迴圈引用,區別是前者在引用移除後仍然指向已經回收的物件,後者則會自動設為nil,所以使用weak會安全一點,因為向nil傳送訊息不會報錯。

7.利用自動釋放池可以避免記憶體峰值的出現。

第六章 塊與大中樞派發

1.下圖是塊的內部結構:

1199576-e79c12feb3bca32e.jpg
1.jpg

上圖中首個變數是個isa指標,所以塊本身是一個物件。那麼塊和普通函式有什麼區別呢?除了塊是個物件外,其實最大的區別就是塊比函式多了個上下文環境,塊內部可以呼叫外部的變數,對應上圖的variables,而descriptor內部則會對捕獲的變數進行管理。

2.塊分為全域性塊NSConcreteGlobalBlock、棧塊NSConcreteStackBlock、堆塊NSConcreteMallocBlock,在ARC中只有全域性塊和堆塊了。

3.利用typedef建立塊,然後將handler塊作為引數傳給方法,以降低程式碼分散程度。這種方法編寫類的時候特別要注意塊的保留環,記得要把塊在適當時機釋放掉,解除保留環。在AFNetworking中,是把所有competition塊儲存在字典中,當請求結束時,再移除,其他開源庫的做法也都大同小異。

4.GCD和NSOperationQueue:前者是純C的API,且更加輕量,後者是Objective-C物件,可以取消操作、設定依賴關係、同一佇列中各操作的優先順序設定。

5.不要使用dispatch_get_current_queue,因為往往A執行緒裡面又有B執行緒,所以在B中檢測當前執行緒就會產生歧義。

第七章 系統框架

1.多用塊列舉,少用for迴圈,另外也可以使用for in這種快速遍歷的方法。

2.loadinitialize裡面的程式碼一定要精簡。不要在裡面呼叫其他類的方法,因為多個類之間執行load的順序是不確定的,而且load不參與繼承機制。initialize會在類被第一次呼叫時執行一次,和load一樣,不要再裡面呼叫其他類的方法。

3.NSTimer會保留目標物件,所以很容易造成迴圈引用,呼叫invalidate方法可以使timer失效,但是別把這項工作交給呼叫者,你永遠無法保證呼叫者一定會呼叫invalidate

結語

這本書其實早就看完了,寫這幾篇部落格時,這本書差不多看了快三遍了,裡面很多知識點對提升程式設計質量還是很有幫助的,在看一些開源iOS框架的時候,很多細節上的處理都能在這本書上找到解釋。

相關文章