Using __block and __weak
我读过这篇文章:"block"关键字是什么意思?它讨论了
我使用它的方式如下:
1 2 3 4 5 | self.someProperty = x; //where x is some object (id) __block __weak VP_User *this = self; //begin a callback-style block this.someProperty = nil; |
我需要同时使用
1 2 3 4 5 | __block NSString *aString = @"Hey!"; void(^aBlock)() = ^{ aString = @"Hello!" }; // without __block you couldn't modify aString NSLog(@"%@", aString); // Hey! aBlock(); NSLog(@"%@", aString); // Hello! |
在ARC中,这会导致变量被自动保留,以便在块实现中安全地引用它。在前面的示例中,当在块上下文中捕获时,
但这在MRC(手动参考计数)中并不成立,在该模型中,变量被引用而不被保留。
标记为EDOCX1[1]会导致变量不被保留,因此块直接引用它,但不保留它。这是潜在的危险,因为在这种情况下,块的寿命比变量长,因为它将引用垃圾内存(并且可能崩溃)。
这是申报文件的相关段落:
In the Objective-C and Objective-C++ languages, we allow the
__weak specifier for__block variables of object type. [...] This qualifier causes these variables to be kept without retain messages being sent. This knowingly leads to dangling pointers if the Block (or a copy) outlives the lifetime of this object.
最后,可以使用
例如,在MRC中,该代码打破了保留周期。
1 2 3 4 | __block typeof(self) blockSelf = self; //this would retain self in ARC! [self methodThatTakesABlock:^ { [blockSelf doSomething]; }]; |
然而,为了在ARC中获得相同的结果,通常需要
1 2 3 4 | __weak typeof(self) weakSelf = self; [self methodThatTakesABlock:^ { [weakSelf doSomething]; }]; |
如果要更改块中的变量值,应该使用
例如:
1 2 3 4 5 6 | __block BOOL result = NO; dispatch_sync(dispatch_get_main_queue(), ^{ ... result = YES; ... }); |
如果要避免保留周期,应该使用
例如。:
1 2 3 4 5 6 | __weak typeof(self) wself = self; self.foobarCompletion = ^{ ... wself.foo = YES; ... }; |
如果有需要,可以将它们组合起来。