Block的本質(zhì):
- block本質(zhì)上也是一個OC對象,它內(nèi)部也有個isa指針;
- block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對象;
Block的數(shù)據(jù)結(jié)構(gòu)

Block的數(shù)據(jù)結(jié)構(gòu)
block的變量捕獲(capture)
為了保證block內(nèi)部能夠正常訪問外部的變量,block有個變量捕獲機(jī)制;
1.局部變量需要捕獲;
2.全局變量不需要捕獲,直接訪問就可以。- 捕獲機(jī)制
局部變量
// auto:自動變量,離開作用域就銷毀
//默認(rèn)就是auto
auto int age = 10;
static int height = 10;
void (^block)(void) = ^{
// age的值捕獲進(jìn)來(capture)
NSLog(@"age is %d, height is %d", age, height);
};
age = 20;
height = 20;
block();
- 打印結(jié)果是:age = 10; height = 20。
- 底層結(jié)構(gòu)如下:
struct __test_block_impl_0 {
struct __block_impl impl;
struct __test_block_desc_0* Desc;
int age;
int *height;
__test_block_impl_0(void *fp, struct __test_block_desc_0 *desc, int _age, int *_height, int flags=0) : age(_age), height(_height) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
1> 創(chuàng)建block的時候,直接 auto修飾 的age封裝到了block中了,block外再修改,不會影響block內(nèi)部的age;
2> static修飾的height,傳到block內(nèi)部的是一個指針;外部修改,也會影響block內(nèi)部的結(jié)果。
為何這樣設(shè)置 ?
- 因為
auto修飾的局部變量,離開作用域后就會銷毀;如果也采用指針訪問,那此時訪問到的就是垃圾數(shù)據(jù)。
擴(kuò)展 :self 會被捕獲嗎 ?
- (void)test {
void (^block)(void) = ^{
NSLog(@"-------%p", self);
};
block();
}
- 會;
-
self其實是一個參數(shù),參數(shù)是一個局部變量。
// test函數(shù)完整寫法如下:
- (void)test(Object *self, SEL _cmd) {
}
