前言
這一篇主要著重對(duì)__block關(guān)鍵字的理解
例子
int main(int argc, const char * argv[]) {
@autoreleasepool {
int a = 10;
void (^helloBlock)(void) = ^(){
printf("%d\n",a);
};
a = 11;
helloBlock();
}
return 0;
}
上面那個(gè)例子運(yùn)行后的結(jié)果是10。我們可以編譯看一下block里面匿名函數(shù)的實(shí)現(xiàn):
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
int a = __cself->a; // bound by copy
printf("%d\n",a);
}
bound by copy這里的注釋表示,block對(duì)它引用的局部變量做了只讀拷貝,也就是說block引用的是局部變量的副本。所以在執(zhí)行block語(yǔ)法后,即使改寫block中使用的局部變量的值也不會(huì)影響block執(zhí)行時(shí)局部變量的值。
那怎么樣才能修改a的值呢?答案就是__block
__block
int main(int argc, const char * argv[]) {
@autoreleasepool {
__block int a = 10;
void (^helloBlock)(void) = ^(){
printf("%d\n",a);
};
a = 11;
helloBlock();
}
return 0;
}
引入__block關(guān)鍵字后,運(yùn)行結(jié)果是11,我們?cè)倬幾g看看block里面匿名函數(shù)的實(shí)現(xiàn)
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
__Block_byref_a_0 *a = __cself->a; // bound by ref
printf("%d\n",(a->__forwarding->a));
}
struct __Block_byref_a_0 {
void *__isa;
__Block_byref_a_0 *__forwarding;
int __flags;
int __size;
int a;
};
我們看到局部變量a變成一個(gè)構(gòu)造體對(duì)象,而不再是一個(gè)整形變量,結(jié)構(gòu)體里包含它原來的整形變量。bound by ref這個(gè)注釋也表明此時(shí)已變成引用傳遞
小小總結(jié)
block可以引用局部變量,但是不能修改它,不然就是編譯錯(cuò)誤,如果想修改它,可以加上__block關(guān)鍵字。但是可以改變?nèi)肿兞俊㈧o態(tài)變量、全局靜態(tài)變量。