Block内存管理

2020-04-20  本文已影响0人  言霏

对block自身内存的管理

对于block,有两个内存管理方法:Block_copy, Block_release;Block_copycopy等效,Block_releaserelease等效;
不管是对block进行retian,copy,release,block的引用计数都不会增加,始终为1;

对引用变量的内存管理

如果该block为NSMallocBlock或者被copy成NSMallocBlock类型则其引用的外界变量的引用计数会被+1,当block释放时外界变量的引用计数-1,而block为NSStackBlockNSGlobalBlock类型时外界变量的引用计数不会变,例子NSMallocBlock

- (void)testBlock {
    NSObject *obj = [[NSObject alloc] init];
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    void(^normalBlock)(int, int) = ^(int a, int b) {
        NSLog(@"normalBlock = %d %@", a + b, obj);
    };
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    NSLog(@"normalBlock %@", normalBlock);
    
    void(^normalCopyBlock)(int, int) = [normalBlock copy];
    NSLog(@"normalCopyBlock %@", normalCopyBlock);
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
}

输出:

2020-04-20 16:03:56.412850+0800 obj.retainCount = 1
2020-04-20 16:03:56.414244+0800 obj.retainCount = 1
2020-04-20 16:03:56.414685+0800 normalBlock <__NSStackBlock__: 0x7ffeefbff538>
2020-04-20 16:03:56.414798+0800 normalCopyBlock <__NSMallocBlock__: 0x100625400>
2020-04-20 16:03:56.414985+0800 obj.retainCount = 2

例子NSGlobalBlock

NSObject *obj = nil;
- (void)testBlock {
    obj = [[NSObject alloc] init];
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    void(^normalBlock)(int, int) = ^(int a, int b) {
        NSLog(@"normalBlock = %d %@", a + b, obj);
    };
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    NSLog(@"normalBlock %@", normalBlock);
    
    void(^normalCopyBlock)(int, int) = [normalBlock copy];
    NSLog(@"normalCopyBlock %@", normalCopyBlock);
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
}

输出:

0-04-20 16:14:01.728789+0800 obj.retainCount = 1
2020-04-20 16:14:01.729195+0800 obj.retainCount = 1
2020-04-20 16:14:01.729499+0800 normalBlock <__NSGlobalBlock__: 0x100002030>
2020-04-20 16:14:01.729582+0800 normalCopyBlock <__NSGlobalBlock__: 0x100002030>
2020-04-20 16:14:01.729636+0800 obj.retainCount = 1

循环引用

MRC下例子:

@property (nonatomic, copy, readwrite) void (^copyBlock)(void);

- (void)testBlock {
    NSObject *obj = [[NSObject alloc] init];
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    self.copyBlock = ^() {
        NSLog(@"copyBlock = %@", obj);
    };
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    NSLog(@"normalBlock %@", self.copyBlock);   
}

输出:

2020-04-20 16:23:12.712386+0800 obj.retainCount = 1
2020-04-20 16:23:12.713195+0800 obj.retainCount = 2
2020-04-20 16:23:12.713557+0800 normalBlock <__NSMallocBlock__: 0x100707d40>

MRC下例子:

@property (nonatomic, copy, readwrite) void (^copyBlock)(void);

- (void)testBlock {
    __block NSObject *obj = [[NSObject alloc] init];
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    self.copyBlock = ^() {
        NSLog(@"copyBlock = %@", obj);
    };
    NSLog(@"obj.retainCount = %ld", obj.retainCount);
    NSLog(@"normalBlock %@", self.copyBlock);
}

输出:

2020-04-20 16:28:59.888767+0800 obj.retainCount = 1
2020-04-20 16:28:59.889190+0800 obj.retainCount = 1
2020-04-20 16:28:59.889454+0800 normalBlock <__NSMallocBlock__: 0x1006518e0>

参考:
https://www.jianshu.com/p/4a6dca34d980

上一篇 下一篇

猜你喜欢

热点阅读