Block : 帶有自動變量(局部變量)的匿名函數。
Block作用 : 用來保存一段代碼,可以在適當的時候調用
Block實質 : 結構體,其里面有一個函數指針
Block應用場景 : 動畫、多線程、集合遍歷、網絡請求回調
Block格式 : ^返回值類型 參數列表 {表達式} (如果返回值類型為void和參數列表為空時是可以省略不寫的)
Block與函數的對比 :
聲明 函數類型 : int ( * funcptr )(int);
聲明Block類型 : int (^ blk)(int);
函數使用typedef : typedef int (^blk_t) (int);使用的時候就直接使用blk_t
Block使用typedef : typedef int (* funcptr) (int);賦值的時候是用函數的地址funcptr func = &addTen;
例子 blk_t blt = ^int (int a){//返回值一般不寫,參數列表是要有()
return 4;
};
截取自動變量值 : Block截獲所使用的自動變量的值,不使用的是不會截獲的。即保存該自動變量的瞬時值,在執行Block的語法后,即使改寫Block中使用的自動變量的值也不會影響Block執行時自動變量的值。
代碼 :
(1)int a = 10;
blk_t block = ^ {
NSLog(@"%d",a);
};
a = 100;
block();//打印之后的結果是10而不是100
(2)Person * p = [[Person alloc]init];
p.name = @"張三";
blk_t block = ^ {
//獲取的是地址,并不是對象的本身
NSLog(@"%@",p.name);
[p1 release];
};
p.name = @"李四";
[p release];
p = nil;
block();
} // [Person name]: message sent to deallocated instance 0x100300170
知識點和注意點 :
(1) 默認情況下,block不能修改外面的局部變量(基本數據類型),除非在前面加__Block
(2) Block語法表達式中使用的局部變量被作為成員變量追加到Block所在的結構體中
(3) Block可以作為函數的參數,調用Block之前一定要判斷,Block可以為nil
(4) 使用Block的時候最好使用typedef
(5) 如果獲取的是引用的話,是可以修改對象的屬性的,不要加__Block也是可以修改的
(6) 在block中使用retain好像沒有效果,但是使用release是可以的
新聞熱點
疑難解答