问题描述
我从公司的文档中发现了以下代码段:
I discover this snippet code from company's document:
__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
// Do stuff
});
它会保留吗?
推荐答案
在块内捕获weak
引用有两个原因.
There are two reasons to capture weak
references within a block.
-
避免保留周期
avoid retain cycles
创建无操作情况.
前者已经被讨论过.第二个更有趣.
The former has been discussed ad-nauseum. The second is more interesting.
示例
如果图像视图已被重新分配(例如,用户已切换到新视图),则无需执行任何操作.没有保留周期的危险,因为图像视图没有引用该块.但是,捕获weak
引用允许在块执行之前重新分配图像视图.因此,如果用户在下载图像之前切换视图,则该块最终将不执行任何操作,因为其weak
引用已被nil
引用.图像视图是否在块的执行过程中被重新分配也无关紧要,因为它只是将对图像视图的操作变为无操作,而不是将整个块变为无操作.
It doesn't need to do anything if the image view has already been deallocated (say the user has switched to a new view). There is no danger of a retain cycle, because the image view has no reference to the block. However, capturing a weak
reference allows the image view to be deallocated before the block executes. Thus, if the user switches views before the image is downloaded, the block ends up doing nothing because its weak
reference has already been nil
ed. It also doesn't matter if the image view is deallocated part way through the block's execution, because it just turns operations on the image view into no-ops, instead of turning the entire block into a no-op.
但是,有时,该块希望无操作行为,但前提是引用开始时(或到达代码路径中的特定点)已经是nil
.如果在执行该块时该对象处于活动状态,则该块必须全部执行.它无法中途停止,因为该对象已被释放到其他线程上.
Sometimes, however, the block wants the no-op behavior, but only if the reference was already nil
when it began (or reached a certain point in the code path). If, at the time the block executes, the object is live, the block has to execute in its entirety. It can't stop half-way through because the object is deallocated on some other thread.
示例
在这种情况下,使用weak
引用捕获字符串是适当的,因此可以由其他某个线程将其释放(不带标题).但是,在块中使用字符串之前,必须strong
ly对其进行捕获,以避免在创建属性字符串时发生崩溃.
In this scenario, it would be proper to capture the string with a weak
reference, so it can be deallocated by some other thread (leading to no caption). However, before the string is used within the block, it must be captured strong
ly to avoid a crash when creating the attributed string.
这篇关于在块中强引用,会保留吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!