int main(int argc, const char * argv[]) {
@autoreleasepool {
int age = 10;
Block block = ^ {
// age = 20; // 无法修改
NSLog(@"%d",age);
};
block();
}
return 0;
}
__block int age = 10;
__isa指针
:__Block_byref_age_0中也有isa指针也就是说__Block_byref_age_0本质也一个对象。__forwarding
:__forwarding是__Block_byref_age_0结构体类型的,并且__forwarding存储的值为(__Block_byref_age_0 *)&age,即结构体自己的内存地址。__flags
:0__size
:sizeof(__Block_byref_age_0),即__Block_byref_age_0所占用的内存空间。age
:真正存储变量的地方,这里存储局部变量10。int main(int argc, const char * argv[]) {
@autoreleasepool {
__block Person *person = [[Person alloc] init];
NSLog(@"%@",person);
Block block = ^{
person = [[Person alloc] init];
NSLog(@"%@",person);
};
block();
}
return 0;
}
__Block_byref_id_object_copy
和__Block_byref_id_object_dispose
__Block_byref_id_object_copy
和__Block_byref_id_object_dispose
对被__block包装成结构体的对象进行内存管理。__forwarding
指针指向的是结构体自己。当使用变量的时候,通过结构体找到__forwarding
指针,在通过__forwarding
指针找到相应的变量。这样设计的目的是为了方便内存管理。通过上面对__block变量的内存管理分析我们知道,block被复制到堆上时,会将block中引用的变量也复制到堆中。__forwarding
指针巧妙的将修改的变量赋值在堆中的__Block_byref_age_0
中。__forwarding
指针的作用
typedef void (^Block)(void); struct __block_impl { void *isa; int Flags; int Reserved; void *FuncPtr; }; struct __main_block_desc_0 { size_t reserved; size_t Block_size; void (*copy)(void); void (*dispose)(void); }; struct __Block_byref_age_0 { void *__isa; struct __Block_byref_age_0 *__forwarding; int __flags; int __size; int age; }; struct __main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0* Desc; struct __Block_byref_age_0 *age; // by ref }; int main(int argc, const char * argv[]) { @autoreleasepool { __block int age = 10; Block block = ^{ age = 20; NSLog(@"age is %d",age); }; block(); struct __main_block_impl_0 *blockImpl = (__bridge struct __main_block_impl_0 *)block; NSLog(@"%p",&age); } return 0; }
__forwarding
其中存储的地址确实是age结构体变量自己的地址