ios - 可选闭包总是会逃逸吗?我们应该使用[weak self]还是[unowned self]呢?

标签 ios swift

UICollectionView中给出以下函数签名。

open func performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil)

互联网上有一些选项,可选闭包总是会逃脱。但是,我真的不确定这是真的,或者这仍然值得商榷。

  1. https://forums.swift.org/t/allowing-escaping-for-optional-closures-in-method-signature/27556
  2. https://gist.github.com/gringoireDM/1f18f3bb4e74e2d914a748d89486db56

对于上述情况,我们是否需要在第一个 block 和第二个黑色中使用[weak self][unowned self]

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    collectionView!.performBatchUpdates({ () -> Void in
        for operation: BlockOperation in self.blockOperations {
            operation.start()
        }
    }, completion: { (finished) -> Void in
        self.blockOperations.removeAll(keepingCapacity: false)

        self.collectionView.reloadData()
    })
}

最佳答案

根据编译器(它拥有对此类事情唯一重要的“意见”),可选的闭包参数始终隐式地@escaping。通过编写一个带有可选闭包并将其标记为 @escaping 的函数来亲自测试这一点。编译器会通知您它已经转义了。

至于您是否应该将self捕获为weakunowned,这取决于情况。首先,我不会将 self 捕获为 unowned,除非您希望程序在您对 self 的生命周期有误时崩溃。 - 你可能会。我宁愿我的程序崩溃也不愿默默地做错事。

但是剩下是否捕获为。我的意见是肯定的,如果您对捕获强引用有任何疑问,请创建一个引用循环以防止其正确取消初始化。但我不会说“总是”或“从不”做某事。如果您能够推断对象的生命周期,以便知道在通常应取消初始化对象之前将运行并释放闭包,那么只需将其捕获为强引用即可。如果您为了闭包而有意延长对象的生命周期,也可以通过强引用进行捕获并且您知道闭包将被执行并处置。

还有一种情况,您知道尽管隐式@escaping它实际上并没有转义。通常这是针对代码库中定义的函数,以便您可以查看实现,但实际上任何时候闭包只是您调用的函数返回之前必须完成的工作的自定义点,您可以推断它实际上并没有逃脱。对于完成处理程序来说情况并非如此,但对于其他事情可能是这样。

这是我的观点。我喜欢认为这是一种知情的说法,但其他人可能不同意。

关于ios - 可选闭包总是会逃逸吗?我们应该使用[weak self]还是[unowned self]呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66923322/

相关文章:

iphone - iPhone 上未收到服务器响应

ios - 调试期间字符串中出现转义双引号

ios - 试图给 UILabel 一个阴影,但它不会出现

ios - 如何使用委托(delegate)将数据从页脚单元格传递到 View Controller ?

ios - 获得正确 reuseIdentifier 的问题

swift - 如何使用 `Codable` 协议(protocol)解码部分双序列化的 json 字符串?

ios - Swift 中 UIViewController 所需的构造函数

ios - 从UIImagePicker到NSMutableArray的图像

ios - 如何为 NSAttributedString 设置默认字体

swift - objective-c block 到 swift