在初始化器中当块处于变量捕获状态

9

考虑以下内容:

id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:MyNotification 
                object:nil 
                 queue:nil 
            usingBlock:^(NSNotification *note) {
                [[NSNotificationCenter defaultCenter] 
                        removeObserver:observer 
                                  name:MyNotification 
                                object:nil
            ];
            // do other stuff here...
    }
];

我正在使用此模式来观察通知一次,然后停止观察。但在ARC下,LLVM告诉我变量“observer”在被块捕获时未初始化。

由于块必须在初始化之前捕获该变量,因为它是初始化程序的一部分,所以我该如何解决这个问题? 使用__block限定符修饰observer是否可以解决问题?


3个回答

18

因为该应用程序的目标是10.6,所以我必须使用__unsafe_unretained代替__weak。尽管名称如此,但可以确保观察者在块运行之前不会被释放吗? - Steveo
@Steveo:我默默地假设使用了自动引用计数(ARC)。如果没有ARC,__block应该就足够了,因为此时块不会对__block变量进行强引用。我会相应地更新答案。 - Martin R
@Steveo:现在我明白你的意思了。你使用ARC,但不能使用__weak。我认为__unsafe_unretained应该能够按预期工作。 - Martin R
@newacct:如果没有使用__weak,当通知被发布并且块被执行后,观察者不会被释放,Instruments会报告一个循环引用。 - Martin R

0

是的,我认为事先将观察者声明为__block id observer;应该可以工作。


0

是的,使用__block将解决问题。

如果没有它,块会在创建时获取变量的值的副本。 (在这种情况下,“未初始化”)有了它,块(实质上)获得了变量本身,因此可以从块内部更改该值。 因此,它还将“跟踪”外部所做的更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接