What is the difference between a __weak and a __bl

2019-06-17 14:44发布

我读Xcode的文件,这里的东西,我感到困惑:

__block typeof(self) tmpSelf = self;
[self methodThatTakesABlock:^ {
    [tmpSelf doSomething];
}];

以下是从文档复制:

A嵌段形成的强引用它捕获变量。 如果您使用self块内,该块形成的强引用self ,所以如果self也有很强的参考块(它通常是这样),较强的参考周期的结果。 为了避免循环,则需要制造出弱(或__block外块)参照自,如在上面的例子。

我不明白什么是“弱(或__block )”是什么意思?

__block typeof(self) tmpSelf = self;

__weak typeof(self) tmpSelf = self;

一模一样的吗?

我发现在文档中另一块:

注意:在一个垃圾收集的环境中,如果你申请都__weak__block修饰的变量,那么该块不会确保它保持活动状态。

所以,我完全摸不着头脑。

Answer 1:

大约从__block的文档

__block变量生活在一个变量的词法作用域和所有块,并宣布或变量的词法范围内创建的块拷贝之间共享存储。 因此,存储将生存堆栈帧的破坏,如果帧中声明的块的任何副本生存超过框架的端部(例如,通过被某处排队以供以后执行)。 在给定的词法作用域多个块可以同时使用一个共享变量。

大约从__weak的文档

__weak指定了不保存引用的对象活着的参考。 当有对象没有强引用弱引用设为零。

因此,他们在技术上是不同的东西。 __block是停止的变量被从外部范围复制到您的块范围。 __weak是一个自我划定弱指针。

请注意我在技术上说,因为你的情况下,他们会做(几乎)同样的事情。 唯一的区别是,如果你正在使用ARC与否。 如果你的项目使用ARC,只是供的iOS4.3及以上,使用__weak。 它保证了基准设为零,如果全球范围内引用发布莫名其妙。 如果您的项目不使用ARC或者是旧的OS版本,使用__block。

有一个微妙的区别就在这里,一定要了解它。

编辑:另一块拼图是__unsafe_unretained。 这修饰符几乎相同__weak但前4.3运行时环境。 但是,没有设置为零,可以让你用挂指针。



Answer 2:

在手动参考计数模式,__block内径x; 有没有保留x的效果。 在ARC模式,__block内径x; 默认为留住X(就像所有其他值)。 要获得ARC下的手动引用计数模式下的行为,你可以使用__unsafe_unretained __block内径x ;. 作为__unsafe_unretained顾名思义,然而,具有非保持着的变量是危险的(因为它可以吊着),因此不鼓励。 两个更好的选择是要么使用__weak(如果不需要支持的iOS 4或OS X v10.6中),或设置__block值为零打破保留周期。

苹果文档



Answer 3:

除了其他的答案__block VS __weak ,还有另一种方式,以避免在方案中保留周期。

@weakify(self);
[self methodThatTakesABlock:^ {
    @strongify(self);
    [self doSomething];
}];

约@Weakify @Strongify宏更多信息



Answer 4:

当使用块自我,应该使用__weak,__block因为它可以保留自我。

如果你需要强大的自我,那么你可以使用这样的:

__weak typeof(self) *weakSelf = self;
[self methodThatTakesABlock:^{
    if (weakSelf) {
        __strong typeof(self) *strongSelf = weakSelf;
        [strongSelf doSomething];
    }
}];


文章来源: What is the difference between a __weak and a __block reference?