JHHK

欢迎来到我的个人网站
行者常至 为者常成

Blocks(五)

目录

循环引用

常见的循环引用的场景

@interface Person : NSObject;
@property (nonatomic, copy) void(^blk)(void);
@end


int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        Person * person = [[Person alloc] init];
        person.blk = ^{
            NSLog(@"person = %@",person);
        };
        
    }
    return 0;
}

循环引用示意图 img

如何解决循环引用的问题
使用__weak __unsafe_unretained 修饰符

Person * person = [[Person alloc] init];
__weak typeof(person) weakPerson = person;
__unsafe_unretained typeof(person) weakPerson2 = person;

解除循环引用的原理示意图

img

另外还有一种解决循环引用的方式,但不推荐。但更有助于我们了解循环引用和解除循环引用。


//会被转换为__block变量
__block Person * person = [[Person alloc] init];

//此处的person是[[Person alloc] init]对象
person.blk = ^{
    NSLog(@"person = %@",person);
    person = nil;//此处的person是block捕获的 __block 变量
};
person.blk();//此处的person是[[Person alloc] init]对象

原理示意图如下

img

但是必须调用person.blk();person=nil;执行才能解除循环引用。


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.