ARC:在变量声明中正确使用__unsafe_unretained __block

时间:2013-12-30 22:08:34

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

下面的设计模式在我的应用中出现了几次。我正在转向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,但是那么糟糕吗?会导致保留周期吗?

1 个答案:

答案 0 :(得分:2)

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

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

来自其他StackOverflow答案,例如thisthis,根据经验显示,如果未使用从块到观察者的弱引用(__weak__unsafe_unretained),则会产生保留周期。因此,我们可以得出结论,observer对象保留(或者是)块。