【问题标题】:ARC: correct use of __unsafe_unretained __block in variable declarationARC:在变量声明中正确使用 __unsafe_unretained __block
【发布时间】:2013-12-30 22:08:33
【问题描述】:

下面的设计模式在我的应用中出现了几次。我正在转换为 ARC。有人可以证实__unsafe_retained __block 的用法是否正确吗?

__unsafe_unretained __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:MyNotification 
    object:nil 
    queue:nil 
    usingBlock:^(NSNotification *note) {
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
        // ...
    }];

一些注意事项:

  • 使用__unsafe_unretained,因为部署目标是 10.6
  • 使用 __block 是因为否则 observer 会被块过早捕获
  • Xcode 的 ARC 迁移工具为我添加了__unsafe_unretained。有必要吗?我意识到没有它,该块将保留observer,但这有那么糟糕吗?会导致保留周期吗?

【问题讨论】:

    标签: objective-c automatic-ref-counting objective-c-blocks nsnotificationcenter weak-references


    【解决方案1】:

    是否需要__unsafe_unretained 的问题归结为否则是否会有保留周期。我们知道,如果它是一个强引用,那么该块将保留observer。那么问题来了,observer 是否保留了区块(或者甚至可能是区块本身)?

    这是一个无法从基本原理中回答的问题。它需要知道observer 对象是什么以及它在内部做什么。不幸的是,这是一个不透明的对象,Apple 并没有告诉我们太多关于它的信息,除了我们必须使用它来移除观察者之外。该文档没有说明该对象是什么或可能在内部保留什么。我认为这是文档中的严重遗漏。

    来自其他 StackOverflow 答案,例如thisthis,根据经验,如果不使用从块到观察者的弱引用(__weak__unsafe_unretained),则会导致保留循环。因此,我们可以得出结论,observer 对象保留(或,是)该块。

    【讨论】:

    • 其他 SO 帖子的有用链接。同意他们应该在文档中提及观察者对阻止的强烈参考!
    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 2017-12-16
    • 2015-12-12
    • 2019-04-19
    • 2020-02-12
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    相关资源
    最近更新 更多