一、截獲自動變數值
//截獲自動變數值 int val = 132; const char *fmt = "val = %d\n"; /* 在blocks中,block運算式使用的是在它聲明之前的自動變數val。 block運算式截獲所使用的自動變數的值,即儲存了該自動變數的瞬間值, 因為block運算式儲存了自動變數的值,所以在執行block文法後,即使改變bock中使用的自動變數的值也不會影響block執行時自動變數的值 所以兩次輸出的結果是一樣的 都是:val = 132 */ void (^blk)(void) = ^{ printf(fmt,val); }; blk(); val = 12345; blk();
二、__block 說明符
//__block說明符 /* 實際上,自動變數值截獲只能儲存在執行block文法瞬間的值,儲存後就不能改寫該值。 如果在block中嘗試改變截獲的自動變數的值,看看會有什麼結果 */ int val = 0; void (^blk)(void) = ^{ val = 1; }; blk();
這個時候就會出現如的錯誤提示啦:
那麼該如何解決呢?-------- 使用 __block 說明符
//若想在block文法的運算式中將值賦給在block文法外聲明的自動變數, //需要在該自動變數的前面附加 __block 說明符,就可以實現在block內賦值。 __block int val = 0; void (^blk)(void) = ^{ val = 1; NSLog(@"val = %d",val); }; blk();
三、截獲的自動變數
上面提到,如果將值賦給block中的自動變數,就會產生編譯錯誤。那麼對於截獲的objective-c對象,調用變更該對象的方法也會產生這樣的編譯錯誤嗎?
請看下面的例子:
id array = [[NSMutableArray alloc]init]; void (^blk)() = ^{ id obj = [[NSObject alloc] init]; [array addObject:obj]; }; blk();
這個是沒有問題的,首先,block中截獲的是NSMutableArray類對象的結構體執行個體指標,這裡是使用截獲的值,所以沒有問題,但是如果向截獲的變數賦值則會產生編譯錯誤。看看下面的例子:
id array = [[NSMutableArray alloc]init]; void (^blk)() = ^{ array = [[NSMutableArray alloc]init]; }; blk();
這個時候就會出現編譯錯誤的提示啦!
顯然,需要給截獲的自動變數附加 __block 說明符才可以解決問題。
四、另外,在使用c語言數組的時候必須小心使用其指標,例如:
const char text[] = "hello world"; void (^blk)(void) = ^{ printf("%c \n",text[2]); };
這個會出現如下的編譯錯誤:
其實在block中,截獲自動變數的方法並沒有實現對c語言數組的截獲,這時可以使用指標解決這個問題。
上面的代碼稍微改動一下就可以了。
const char *text = "hello world"; void (^blk)(void) = ^{ printf("%c \n",text[2]); }; blk();
運行時就可以輸出 字元:l
五、
Block會保持一個strong指標指向block內被使用的所有對象,即這些被引用的對象會保持在heap中直到block生命週期結束。
MemoryCycle(記憶體迴圈)問題:
以下(在控制器類中)定義屬性並使用Block 的代碼:
@property(nonatomic ,strong) NSMutableArray *myBlocks;// block array
[self.myBlocksaddObject:^{ //Block可當作對象使用
[selfdoSomething];
}];
由於 Block 內引用了 self,因此self(通過myBlocks 屬性) 和 Block 均有 一個strong 指標指向彼此,此時self 及 Block 均無法從記憶體中釋放!
解決方案:
定義一個 weak 指標:
__weakMyClass *weakObj = self;
//arrayofblocks
@property(nonatomic,strong)NSArray*myBlocks;
[self.myBlocks addObject:^{
[weakObjdoSomething];
}];
Block擁有一個指向weakObj 的 weak 指標,self 擁有一個指向 myBlock 的 strong 指標。