iOS Block的内存管理
程序员文章站
2024-02-29 22:26:52
...
__block与__weak对于block在ARC下内存管理
_block 变量 内部实现,实际上用一个新的__Block对象当前变量包装,block内部通过引用当前包装对象实现对于外界变量的持有。此时block内部对于__Block包装的对象为强持有,ARC如果对于当前Block有强引用,则会将当前block从栈copy到堆上,此时如果之前变量在栈上,则会一并copy到堆上。
如果block没有访问auto变量,那么block则为__NSGlobalBlock_类型。如果block访问了auto变量,MRC下或者ARC下没有强引用此block,则为__NSStackBlock,否则就会被copy到堆上,为__NSMallocBlock_类型.
测试代码
typedef void(^Block)(void);
int age = 10;
typedef void(^Block)(void);
int main(int argc, const char * argv[]) {
@autoreleasepool {
__block int num = 10;
NSObject *obj = [[NSObject alloc] init];
Block block = ^{
num= 20;
NSLog(@"----%d, obj=%@", num, obj);
};
NSLog(@"%@", ^{
NSLog(@"age= %d", age);
});
NSLog(@"%@", ^{
NSLog(@"num- %d", num);
});
block();
NSLog(@"%@", block);
NSLog(@"result___num:%d", num);
}
}
/*
//控制台输出
2020-04-14 22:12:01.518998+0800 Interview03_block[59707:1481097] <__NSGlobalBlock__: 0x100001070>
2020-04-14 22:12:01.519416+0800 Interview03_block[59707:1481097] <__NSStackBlock__: 0x7ffeefbff458>
2020-04-14 22:12:01.519501+0800 Interview03_block[59707:1481097] ----20, obj=<NSObject: 0x10052e9a0>
2020-04-14 22:12:01.519566+0800 Interview03_block[59707:1481097] <__NSMallocBlock__: 0x100537e90>
2020-04-14 22:12:01.519607+0800 Interview03_block[59707:1481097] result___num:20
*/
用Clang编译成cpp文件,查看cpp代码结构如下
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-9.0.0 main.m
当block在栈上时,并不会对__block变量产生强引用
当block被copy到堆时, 会调用block内部copy函数(copy函数内部会调用_Block_object_assign函数)实现对__block变量形成强引用
如果是OC对象,_Block_object_assign则会根据OC对象的修饰符决定是否为强引用,如果为__weak则为弱引用,默认OC对象为强引用。
当__block修饰对象类型时分析