1. 程式人生 > >《Objective-C 高階程式設計 iOS與OS X多執行緒和記憶體管理》 核心札記二

《Objective-C 高階程式設計 iOS與OS X多執行緒和記憶體管理》 核心札記二

核心札記二   Blocks   閱讀地點:北京 肯德基店  2014.4.7

1,Blocks 是C 語言的擴充功能,用一句話概述就是:帶有自動變數(區域性變數,作者將此翻譯成自動變數)的匿名函式;

2,Blocks 類似C語言裡面的函式指標,特別在C++裡面它叫做Lambda,它與C函式唯一不同有兩點:a)沒有函式名,b)帶有 ^(讀caret),格式為 ^ 返回值型別 引數列表 表示式,如 ^ int (int count){ return count+1; } ,也可以省略返回值型別和引數列表,如^{ print} ;

3,對比函式指標和Blocks使用方法:

函式指標定義:int func (int count)( return count +1) ;  int (*funcptr)(int) = &func;

函式指標使用:int result = (*funcptr)(10);

Blocks定義:int (^blk)(int) = ^(int count){return count+1;};

Blocks使用:int result = blk(10);

4,通常定義一個block我們通常用typdef 來解決 ,如宣告 typedef int ^(blk_t)(int); 定義個變數 blk_t blk_t_demo; 使用 int result =  blk_t_demo(10);

5,Blocks會擷取自動變數,即區域性變數的瞬間值,儲存後不能修改,所以想修改區域性變數可以在前面加入 __block 修飾符,block實質通過clang預測即為 OC物件;

6,Block 和 __block 變數都是在棧上的結構體,為了解決自動變數區域性使用特性,Block 採用了從棧上覆制到堆上來解決這個問題,即使區域性失效釋放了,堆上的可以繼續使用,即[blk copy];

7 ,從棧複製到堆過程中,容易引起迴圈引用,建議變數前面增加__weak 修飾符來避免,尤其在MRC下__block說明符被用來避免Block中的迴圈引用,這是由於Block從棧複製到堆,若Block使用的變數為附有__Block 說明符的id型別或物件型別的自動變數,不會被retain,否則會被retain,即兩種方式,如 id _weak temp = self; 和 __block id temp = self; 來達到防止迴圈引用。

總結:作者深入淺出的講解了Block的前世今生,可謂挖盡骨髓來預測和證實這種匿名函式為什麼被蘋果工程師如此的推崇,這就是看中了它的簡潔,高效率和易用性,同時也是對其他語言開發者的一種示好,關鍵要掌握好Block裡面的記憶體釋放問題,尤其是迴圈引用,在使用時候要特別注意。

趣聞:在讀書期間,旁邊出現了一個日本朋友問附近哪裡有書店,正好這本書也是日本作者寫的,不過這朋友的普通話的確不錯,略聊幾句,算是致敬作者了..