【问题标题】:Why is this completion block correctly being called?为什么正确调用此完成块?
【发布时间】:2016-09-23 23:15:02
【问题描述】:

为什么正确调用了这个完成块?

CompletionBlock comp = ^(BOOL enabled) {
            //enabled is being correctly set
            NSLog(@"result: %i", enabled);
};

@autoreleasepool {
    Monitor *monitor = [[Monitor alloc]initWithCompletionBlock:comp];
    monitor = nil;
}

监视器将在监视器实例化 10 秒后启动 NSTimer 以调用完成块。

监视器在内部确实有对 comp 的引用(通过 @property (nonatomic) CompletionBlock compblock;),但循环引用的成分似乎不存在,因为没有引用监视器。

这是正常行为吗?这是我可以指望的行为吗?这对我来说真的没有意义。

【问题讨论】:

  • 没有看到Monitor类的实现,我们真的不能给你一个正确的答案。

标签: objective-c closures automatic-ref-counting


【解决方案1】:

大概Monitor 实例是这里的目标。 NSTimer 保留其目标,以避免在触发时向释放的对象发送消息而导致崩溃。* 当前运行循环在调度时保留计时器。

这是正常行为,you can rely on it

目标
向其发送消息的对象 [...] 计时器保持对target...的强引用...

事实上,您必须考虑到这一点,以免在计时器与其目标之间创建保留循环。


*NSTimer 早于自动清除弱引用很长时间。

【讨论】:

  • 你是对的,Monitor 对象是目标。我也在使用重复:否。该文档指出,一旦计时器触发,它将失效。我猜这意味着选择器完成后?否则 GC 有可能做得太早了。
  • 是的,计时器在被告知其目标执行选择器之前不会使自己失效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 1970-01-01
  • 2019-01-17
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多