為什么不加__block不能修改變量值
普通變量拇勃,數(shù)值型或?qū)ο笮图枇粒瑳]有加__block時,Block捕獲的是變量误债,不是變量的地址浸船,因為在函數(shù)里對變量做修改不起任何作用,所以編譯器層面禁止對捕獲的變量進行修改寝蹈。如果捕獲的是變量的地址的話李命,就可以修改,例如:
static int num = 10;
bbk blk = ^{
num++;
};
NSLog(@"%d", num);
blk();
NSLog(@"%d", num);
輸出結(jié)果:
10
11
編譯成C++箫老,看看對靜態(tài)變量num做了什么:
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
int *num;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_num, int flags=0) : num(_num) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
可以看到Block捕獲的是靜態(tài)變量的地址"int *num"封字,所以可以根據(jù)這個指針對靜態(tài)變量做修改。
為什么加了__block就能修改變量值
使用了__block耍鬓,可以修改變量值阔籽,根本原因還是因為獲取到了變量的地址,看一下這段代碼:
int main(int argc, const char * argv[])
{
__block int a = 100;
Blk blk_t;
{
blk_t = ^(id obj){
a = 200;
};
}
blk_t(@"Hello");
return 0;
}
編譯成C++看一下我們的“a=200”究竟做了什么牲蜀,
static void __main_block_func_0(struct __main_block_impl_0 *__cself, id obj) {
__Block_byref_a_0 *a = __cself->a; // bound by ref
(a->__forwarding->a) = 200;
}
__forwarding指針是一個指向自己__block實例的指針(當在棧上時)笆制,又通過__forwarding指針取到了變量a的地址進行賦值,所以最終是拿到了變量的地址涣达,所以可以對變量進行修改在辆。