首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用__block和__weak

使用__block和__weak
EN

Stack Overflow用户
提问于 2013-10-07 22:51:18
回答 2查看 19.9K关注 0票数 27

我已经阅读了这个帖子:What does the "__block" keyword mean?,它讨论了__block的用途,但我对其中一个答案感到困惑。它说__block是用来避免保留周期的,但它下面的注释让我不确定。

我使用的是这样的东西:

代码语言:javascript
复制
 self.someProperty = x; //where x is some object (id)
 __block __weak VP_User *this = self;

 //begin a callback-style block
     this.someProperty = nil;

我需要同时使用__block__weak吗?这样看起来有什么明显的问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-07 22:59:40

__block是一个存储限定符。它指定变量应该由块直接捕获,而不是复制它。这在需要修改原始变量的情况下非常有用,如下例所示

代码语言:javascript
复制
__block NSString *aString = @"Hey!"; 
void(^aBlock)() = ^{ aString = @"Hello!" }; // without __block you couldn't modify aString
NSLog(@"%@", aString); // Hey!
aBlock();
NSLog(@"%@", aString); // Hello!

在ARC中,这会导致变量被自动保留,以便可以在块实现中安全地引用它。在前面的示例中,当在块上下文中捕获时,将向aString发送一条retain消息。

请注意,这在MRC (手动引用计数)中并非如此,在MRC中,变量被引用而不被保留。

将其标记为__weak会导致变量不被保留,因此块直接引用它,但不保留它。这是潜在的危险,因为如果块的寿命比变量长,因为它将引用垃圾内存(并且可能会崩溃)。

以下是clang doc中的相关段落

在Objective-C和Objective-C++语言中,我们允许对object类型的__block变量使用__weak说明符。..。此限定符导致保留这些变量,而不发送保留消息。如果块(或副本)的生命周期超过此对象的生命周期,则这会故意导致悬空指针

最后,__block可用于避免强引用周期(也称为保留周期)的说法在ARC上下文中是完全错误的。由于在ARC中,__block会导致变量被强引用,所以它更有可能导致它们。

例如,在MRC中,此代码打破了保留循环

代码语言:javascript
复制
__block typeof(self) blockSelf = self; //this would retain self in ARC!
[self methodThatTakesABlock:^ {
    [blockSelf doSomething];
}];

然而,为了在ARC中实现相同的结果,您通常会这样做

代码语言:javascript
复制
__weak typeof(self) weakSelf = self;
[self methodThatTakesABlock:^ {
    [weakSelf doSomething];
}];
票数 60
EN

Stack Overflow用户

发布于 2013-10-07 22:59:13

如果你想改变块中的变量值,你应该使用__block

例如:

代码语言:javascript
复制
__block BOOL result = NO;
dispatch_sync(dispatch_get_main_queue(), ^{
  ...
  result = YES;
  ...
});

如果您希望避免保留周期,则应使用__weak

例如:

代码语言:javascript
复制
__weak typeof(self) wself = self;
self.foobarCompletion = ^{
  ...
  wself.foo = YES;
  ...
};

如果需要,您可以将它们组合在一起。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19227982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档