Ios 何时以及为什么我要使用ARC将局部变量声明为_弱?

Ios 何时以及为什么我要使用ARC将局部变量声明为_弱?,ios,iphone,xcode,automatic-ref-counting,weak-references,Ios,Iphone,Xcode,Automatic Ref Counting,Weak References,在那里,他介绍了如下内容: __weak Foo *_weakFoo = [object foo]; 为什么我要对一个局部的临时变量这样做__弱是一个归零引用,一旦被引用对象被解除分配,它将自动将_weakFoo指针设置为nil。此外,仅在iOS>=5中可用 当我这么做的时候,什么时候会遇到麻烦 Foo *_weakFoo = [object foo]; 这总是期望返回一个对象或nil。我猜是这样的: Foo *_weakFoo = [object foo]; [self doSomethi

在那里,他介绍了如下内容:

__weak Foo *_weakFoo = [object foo];
为什么我要对一个局部的临时变量这样做__弱是一个归零引用,一旦被引用对象被解除分配,它将自动将_weakFoo指针设置为nil。此外,仅在iOS>=5中可用

当我这么做的时候,什么时候会遇到麻烦

Foo *_weakFoo = [object foo];
这总是期望返回一个对象或nil。我猜是这样的:

Foo *_weakFoo = [object foo];
[self doSomethingStupid]; // does something bad so foo gets deallocated
[_weakFoo doIt]; // CRASH! msg sent to deallocated instance 0x123456
有一件事仍然困扰着我:什么时候它知道我不再需要一个对象了?我认为,当我将指针设置为nil或其他对象时,它会发现之前引用的对象不再是该所有者所需要的,因此可能会消失。但关键是:我把它设为零。所以无论如何都是零


那么,什么时候局部变量的“弱”才有意义,我必须在其他地方做什么疯狂的事情才能真正需要它呢?

如果我必须在块内部操纵
self
以避免保留循环,我会使用
局部变量。考虑这个例子,在这里我使用GCD和块来执行一个字符串的网络请求,然后将它设置在类声明的标签上,在这种情况下,<代码> TurtListVIEW控制器
__weak TurtlesViewController *weakSelf = self;
dispatch_queue_t networkQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(networkQueue, ^{

    // Kick off a network task for some data that is going to populate a label declared on our class
    NSString *returnString = [networkDataSource retrieveTurtleTime];

    // Dispatch back to the main thread to populate the UILabel
    dispatch_async(dispatch_get_main_queue(), ^{

        // Using self.label here creates a retain cycle. Self owns the block and the block has captured self
        self.label.text = returnString;

        // Instead, we use weakSelf for our reference to the label as it will be torn down by ARC at the end of the loop.
        weakSelf.label.text = returnString;
    });
});

但是怎么会有保留周期呢?@openfrog-这个特定的块可能不是保留周期的最大风险,但我遇到的是基于块的通知观察器(使用NSNotificationCenter的
-addObserverForName:object:queue:usingBlock:
)。如果在对象中设置这样一个观察者,并参考
self
上的某个内容,则将设置一个循环,因为对象将保持块,而块将保持对象。写了这篇文章后,我意识到这不是最好的示例,因为dispatch\u async()复制块,但只复制到方法结束。一个更好的例子是使用NSBlockOperation,因为这样的实例在对象的生命周期中拥有传入的块,这使得保留周期更有可能。