int main(int argc, const char * argv[]) {
@autoreleasepool {
__block int a = 10;
void(^block)(void) = ^{
a = 20;
NSLog(@"=====%d",a); // 20
};
block();
}
return 0;
}
__block 之所以能修改int a 主要是编译器将 int a包装成一个对象(__Block_byref_a_0)
通过命令行 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m 转成C++代码 (这个不一定百分之百准确)
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-14.0.0 main.m (可以指定版本)
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
// 将int a 包装成一个对象
struct __Block_byref_a_0 {
void *__isa;
__Block_byref_a_0 *__forwarding; // 指向他自己
int __flags;
int __size;
int a;
};
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_a_0 *a; // by ref
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags=0) : a(_a->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
__Block_byref_a_0 *a = __cself->a; // bound by ref
(a->__forwarding->a) = 20;
NSLog((NSString*)&__NSConstantStringImpl__var_folders_mw_fwc7934j2ys468j_k__28twh0000gn_T_main_46a82c_mi_0,(a->__forwarding->a));
}
static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->a, (void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}
static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
void (*dispose)(struct __main_block_impl_0*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};
int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
__attribute__((__blocks__(byref))) __Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0), 10};
void(*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344));
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
}
return 0;
}
补充:
NSMutableArray *array = [NSMutableArray array];
void(^block)(void) = ^{
// 只是使用array这指针 而不是修改array指针的值
// 所以不用加__block
[array addObject:@"123"];
};
block();