块中具有强引用的弱变量:不创建保留循环?
Posted
技术标签:
【中文标题】块中具有强引用的弱变量:不创建保留循环?【英文标题】:weak variable with a strong reference in a block: does not create a retain cycle? 【发布时间】:2014-11-11 14:56:30 【问题描述】:为什么当我们将弱引用传递给块内的强引用时它会起作用?如果块中的局部变量被保留,这应该在self
中添加一个保留,从而创建这个糟糕的保留循环?
这是一个例子:
__weak id weakSelf = self;
[self.operationQueue addOperationWithBlock:^
NSNumber* result = findLargestMersennePrime();
[[NSOperationQueue mainQueue] addOperationWithBlock:^
MyClass* strongSelf = weakSelf;
strongSelf.textLabel.text = [result stringValue];
];
];
【问题讨论】:
【参考方案1】:当您创建或复制一个块时(例如,它可以在您将其调度到 gcd 时被复制),引用的变量将被捕获(除非使用 __block 说明符声明)。保留强引用,不保留弱引用。
当您创建本地 strongSelf
变量时,它会在块 执行 时使 self
保持活动状态(即,当它没有被执行并且位于属性中时,没有强引用)。当您直接引用 self
时 - self
被捕获并保留,现在它在 block 处于活动状态时保留 self
。
__weak id weakSelf = self;
[self.operationQueue addOperationWithBlock:^
NSNumber* result = findLargestMersennePrime();
[[NSOperationQueue mainQueue] addOperationWithBlock:^
MyClass* strongSelf = weakSelf; // strong reference when block executes
[self foo]; // strong reference when block created/copied
strongSelf.textLabel.text = [result stringValue];
];
];
看到区别了吗?如果你用直接的self
引用杀死所有指向对象的强指针,那么块内仍然有一个强引用,即被捕获并保留的那个。同时本地 strongSelf
指针仅在块执行时持有对 self
的强引用,因此,如果 self
已经死,weakSelf
将为 nil,strongSelf
将获得 nil 值。
【讨论】:
【参考方案2】:不,它不会创建一个循环,因为 self 没有被捕获得那么强! :)
strongSelf 是一个保留自身的强引用,但是因为strongSelf 是一个本地变量,它在块完成并且保留计数下降时释放
【讨论】:
以上是关于块中具有强引用的弱变量:不创建保留循环?的主要内容,如果未能解决你的问题,请参考以下文章