美文网首页
ARC环境下循环引用案例

ARC环境下循环引用案例

作者: 4f080ccfcf32 | 来源:发表于2017-09-24 19:52 被阅读5次

    虽然ARC环境帮助我们做了很多事情,完美的解决了大多数情况下对象的自动释放。但在使用black的情况下,如果不注意,循环引用还是会发生的,导致对象无法释放。

    循环引用发生不一定会造成直观的现象,但某些场景下却会带来问题,比如在某个 Controller 注册了 self 为观察者,一般会在 dealloc 中移除观察者。但如果页面无法释放,再次进入这个 Controller 就会重复注册观察者,会出现通知重复调用的问题。

    案例一:

    [self.model doSomething:^(NSNumber *id) {
        self.name = [NSString stringWithFormat:@"我的 id 是%@",id];
    }];
    

    上面的代码,self 强引用了 model, model 也强引用了doSomething 这个 block,而 block 的回调中又调用了self 的 name 属性,会导致 block 又强引用了 self,形成循环引用,导致 self 无法释放。

    解决办法:

    __weak typeof(self) weakSelf = self;
    [self.model doSomething:^(NSNumber *id) {
        typeof(weakSelf) strongSelf = weakSelf;
        strongSelf.name = [NSString stringWithFormat:@"我的 id 是%@",id];
    }];
    

    或者

    [self.model doSomething:^(NSNumber *id) {
        self.name = [NSString stringWithFormat:@"我的 id 是%@",id];
    }];
    self.model = nil
    

    案例二:

    @interface TestViewController ()
    {
        NSInteger count;
    }
    
    @property (nonatomic, strong) TestModel *model;
    @end
    
    
    self.model = [[BHFeiModel alloc] init];
    self.model.blockTest = ^{
        count = 9;
    };
    

    上面的代码乍一看,也没有问题, block 里没有出现 self 。但试验过你会发现,界面依然无法释放。

    因为试用 {} 直接声明的,虽然不用 self 进行访问,但实质上和 @property 是一样的,还是会调用 self

    因此,改用 @property 声明,然后通过 self 进行访问:

      self.model = [[BHFeiModel alloc] init];
        __weak typeof(self) weakSelf = self;
        self.model.blockTest = ^{
            typeof(weakSelf) strongSelf = weakSelf;
            strongSelf.imageCount = 9;
        };
    
    

    这样便解决了循环引用导致界面无法释放的问题。

    相关文章

      网友评论

          本文标题:ARC环境下循环引用案例

          本文链接:https://www.haomeiwen.com/subject/wqklextx.html