何时以及为什么要使用ARC将局部variables声明为__weak?
迈克·阿什把这个介绍写到了ARC ,他介绍了这样一些内容:
__weak Foo *_weakFoo = [object foo];
为什么我要为一个本地临时variables做这个? __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
还有一件事让我感到困惑,那就是:什么时候知道我不再需要一个对象? 我会争辩说,当我设置一个指针为零或其他的东西时,会发现先前引用的对象不再需要这个所有者,因此可能会消失。 但重点是:我把它设置为零。 所以它无论如何是零!
那么,什么时候__弱化一个局部variables是有道理的,那么我必须在别的地方做什么样的疯狂的事情,以至于我真的需要这个?
我使用__weak
局部variables,如果我必须操纵一个块内的self
,以避免保留周期。 考虑这个例子,我使用GCD和块来为一个string执行一个networking请求,然后将它设置在类声明的标签上,在这个例子中是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; }); });