欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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对象为强引用。
iOS Block的内存管理iOS Block的内存管理
当__block修饰对象类型时分析

相关标签: block