objective-c - block 中的强引用,会被保留吗?

标签 objective-c objective-c-blocks

我从公司文档中发现这段代码:

__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(),
^{
      __strong __typeof(weakSelf)strongSelf = weakSelf; 
      // Do stuff
});

它会被保留吗?

最佳答案

在 block 中捕获引用有两个原因。

  1. 避免保留循环

  2. 创建无操作情况。

前者已经被讨论得令人作呕。第二个更有趣。

示例

The block in question is a completion handler for an image download. When the download is complete, it is to be displayed in an image view.

如果 ImageView 已经被释放(比如用户已经切换到一个新 View ),它不需要做任何事情。没有保留循环的危险,因为 ImageView 没有引用 block 。但是,捕获 weak 引用允许在 block 执行之前释放 ImageView 。因此,如果用户在下载图像之前切换 View ,该 block 最终什么都不做,因为它的 weak 引用已经被 nil 了。 ImageView 是否在 block 执行的中途被释放也无关紧要,因为它只是将 ImageView 上的操作变成空操作,而不是将整个 block 变成空操作。

然而,有时该 block 需要空操作行为,但前提是引用在开始时(或到达代码路径中的某个点)已经是nil。如果在 block 执行时对象处于事件状态,则 block 必须完整执行。它不能中途停止,因为该对象已在其他线程上释放。

示例

The purpose of the completion block is to add a caption, defined by a string, to the image. If the string has been deallocated already, no caption is to be added. However, if the string is still live when post-processing begins, it must remain live to avoid trying to create an attributed string with a nil reference, because that leads to a crash.

在这种情况下,使用 weak 引用捕获字符串是合适的,这样它就可以被其他线程释放(导致没有标题)。但是,在 block 中使用字符串之前,必须strongly 捕获它以避免在创建属性字符串时发生崩溃。

关于objective-c - block 中的强引用,会被保留吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37849675/

相关文章:

objective-c - 复制 block (即 : copying them to instance variables) in Objective-C

objective-c - 基于 UIView block 的动画重绘

methods - Objective-C 中方法和 block 的区别

iphone - UILabel 未使用另一个类的值进行更新

ios - 如何获取 heightForRowAtIndexPath 中的单元格?

ios - 了解使用对象 C 进行编程的 block

objective-c - 您可以将代码附加到 Objective-C block 变量吗?

ios - 将 UINavigationBar alpha 更改为 0,然后返回主页并返回应用程序。 navigationBar alpha 更改为 1

iphone - 如何在 iOS 中处理 1 到 3 个手指滑动手势

ios - 在 UITableView 中插入项目会导致应用程序崩溃