Mike Ash has written this introduction to ARC他介绍了类似的内容:
__weak Foo *_weakFoo = [object foo];
为什么我要为本地临时变量执行此操作? __weak是一个归零引用,只要引用的对象被释放,它就会自动将_weakFoo指针设置为nil。此外,__ weak仅适用于iOS> = 5。
当我这么做时,我什么时候会遇到麻烦?:
Foo *_weakFoo = [object foo];
总是希望返回一个对象或零。我猜是这样的:
Foo *_weakFoo = [object foo];
[self doSomethingStupid]; // does something bad so foo gets deallocated
[_weakFoo doIt]; // CRASH! msg sent to deallocated instance 0x123456
仍然让我厌烦ARC的一件事是:它何时知道我不再需要一个物体了?我认为当我设置一个指向nil或其他东西的指针时,它会发现此所有者不再需要先前引用的对象,因此可能会消失。但问题是:我把它设置为零。所以它无论如何都是零!
那么什么时候__weak的局部变量才有意义,我必须在其他地方做什么样的疯狂才能真正需要呢?
答案 0 :(得分:9)
如果我必须操作块内的__weak
以避免保留周期,我会使用self
局部变量。考虑这个例子我正在使用GCD和块来执行字符串的网络请求,然后在类声明的标签上设置它,在本例中为TurtlesViewController
。
__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;
});
});