【问题标题】:What's the best way to manage memory when a ivar inside a block might be released?当块内的 ivar 可能被释放时,管理内存的最佳方法是什么?
【发布时间】:2015-03-17 18:48:05
【问题描述】:

假设你有这样的东西:

 ivarOutsideOfBlock = @"foo"; 

 [doSomethingThatTakesAwhile start:^(NSError *error) {
        if(!error){
            ivarOutsideOfBlock = @"somethingElse";
            // Might crash because iVarOutsideOfBlock may no longer exist
        }
  }];

此时,假设对 ivar(视图控制器)的引用被释放。代码会崩溃吗(无效地址)?

这方面的最佳做法是什么?是把ivar转成视图控制器上的强属性吗?

【问题讨论】:

  • 一个对象将调用回调(start 块)。此对象将保留您的初始对象。

标签: ios objective-c memory-management objective-c-blocks


【解决方案1】:

Block 内部对 ivar 的引用隐式为 viewController->ivar,并且 Block 对 ivar 的 owner 进行了强引用。在 Block 之前不会被释放。

看起来您实际上有一个retain cycle,因为块的所有者与引用的对象相同。这是有问题的:Block 和另一个对象相互保持活动状态,并且两者都不能被释放。

【讨论】:

  • 我不相信有一个保留周期,该块没有像在属性中那样被 self 明确保留。它很容易测试,向类添加一个 dealloc 方法并查看它是否触发。遗憾的是,拥有大量知识的开发人员难以确定是否存在保留循环 wrt 块。我看到很多不需要的 weakSelf/strongSelf,当这引起开发人员的注意时,我听到:“我为什么要删除它?”当我想知道“你为什么想要不必要的代码。”
  • 是的,你说的很对,@Zaph,完全不确定是否存在循环。取决于doSomethingThatTakesAWhile所引用的对象的所有权。
猜你喜欢
  • 1970-01-01
  • 2011-01-12
  • 2011-11-01
  • 2013-02-27
  • 1970-01-01
  • 2010-10-08
  • 2018-07-24
  • 2011-03-25
  • 1970-01-01
相关资源
最近更新 更多