【问题标题】:Swift - @escaping and capture list clarificationSwift - @escaping 和捕获列表澄清
【发布时间】:2023-03-03 02:29:01
【问题描述】:

我试图尽可能多地挖掘这个主题,但我仍然有一些事情没有在我的脑海中解决,我会很感激能得到关于它们的澄清......所以我做了一些问题..

  1. 编译器如何知道我必须在后台线程上添加@escaping,并以此强制我使用它?
  2. 使用@escaping 是否需要付费?如果没有.. 为什么不总是标记?如果我用@escaping 标记关闭,即使我真的不需要它,会出现什么问题?当我尝试这样做时..我的代码没有问题,无论有没有@escaping,结果都保持不变。
  3. 使用捕获列表 [weak self] [unowned self] 的成本是多少? 我知道它会复制该对象,所以我想暂时它会占用更多内存,但在使用结束时,该副本将从内存中删除..那么,使用它还有更多缺点吗?

【问题讨论】:

  • 你从哪里读到的捕获列表 [weak self] [unowned self] 复制了那个对象?
  • 我想我没听懂。那么“捕获”是什么意思,就无主的自我而言​​,它在幕后是如何运作的?闭包如何在不拥有对象的情况下使用 self?也许这个问题需要与stackoverflow分开
  • 好吧,看看我的编辑,我再次尝试了更详细的描述

标签: swift escaping closures unowned-references capture-list


【解决方案1】:

简短回答

  1. 编译器使用不同的进程来分析代码。有很多关于大学编译器如何工作的讲座。所以很难给你一个正确的答案。
  2. 使用你需要的东西。很难估计这要花多少钱。 @escaping 和 @no-escaping 有不同的用例。
  3. 我没有看到缺点。使用弱是防止零售周期和内存泄漏的好方法。

说明

1:所以我真的不知道这个编译器究竟是如何工作的。但是,如果您想了解编译器通常是如何工作的,请阅读一些轻量级文章,例如 one

在我的想法中,编译器会进行词法分析、语法分析和语义分析。所以编译器会检测你是否需要转义。

2:闭包是 swift 中的一个概念,即“在事情完成后做事”。有关更多详细信息,请查看 documentationhere

以下信息大量基于本文what-do-mean-escaping-and-nonescaping-closures-in-swift

在 Swift 1 和 2 中,闭包默认是 @escaping。由于 Swift 3 闭包是@no-escaping。

@no-escaping clousures

当你在函数的参数中传递一个闭包时,在函数体被执行并返回编译器之前使用它。当函数结束时,传递的闭包超出范围,在内存中不再存在。

简单地说,这对开发人员来说是一种舒适的内存处理,因为他不需要关心任何事情。

@escaiping 闭包

@escaping 闭包有两个用例:

存储:当您需要将闭包存储在全局变量中时,调用函数的内存中存在的属性或任何其他存储将被执行并返回编译器。

异步执行:当你在调度队列上异步执行闭包时,队列会为你保存在内存中的闭包,以备将来使用。在这种情况下,您不知道何时执行闭包。

来自 Apple 文档

当闭包被传递为 函数的参数,但在函数返回后调用。 [...] 你可以在参数类型之前写 @escaping 表示允许闭包逃逸。

仅供参考:闭包标志着一个操作是异步的,而不是在后台线程上强制执行。

3:我没有看到使用它的缺点。使用弱是防止零售周期和内存泄漏的好方法。当你得到一个稳定的应用程序时,你应该忽略潜在的成本。但我再说一遍:使用你需要的东西。对于内存泄漏,这是一件棘手的事情,而且通常很难找到。

请参阅https://stackoverflow.com/a/34566876/4420355 以获得有关委托和内存泄漏的非常好的答案。这篇文章中还有很多进一步的链接。如果您阅读它们,您将更好/更好地了解内存泄漏将如何发生以及如何防止它们。

也看看这个帖子,和你的有点相似https://stackoverflow.com/a/46245943/4420355

编辑为 3

提问者:

我想我没听懂……那么“捕获”是什么意思,就无主自我而言,它在幕后如何真正起作用?闭包如何在不拥有对象的情况下使用 self?也许这个问题需要与stackoverflow分开

Can a local variable's memory be accessed outside its scope?帖子示例的启发

您租了一间酒店房间。您第二天早上退房,锁上门,但“忘记”归还您的钥匙。你偷了钥匙!没有备用钥匙。所以酒店房间是锁着的。酒店老板不能再租这个房间了。现在有很多客人偷钥匙。有时每个房间实际上都是免费的,但上锁了。

有点幻想,租户是一个关闭。他租用房间(创建对房间实例的引用)。他睡在那里(异步操作)。他应该归还他的钥匙,但他没有。

据我了解,闭包并不拥有该对象。它是闭包和实例属性之间的引用。

苹果文档:

如果将闭包分配给 类实例的属性,并且该闭包的主体捕获 实例。这种捕获可能会发生,因为闭包的主体 访问实例的属性,例如 self.someProperty,或 因为闭包调用了实例上的一个方法,比如 self.someMethod()。在任何一种情况下,这些访问都会导致关闭 “捕捉”自我,创造强大的参考循环。

您可以使用weakunowned 解决这个强循环。在我看来,苹果用来解释weakunowned 之间区别的图片非常好:参见Automatic Reference Counting

【讨论】:

  • 喜欢你关于酒店的插图,真的很有帮助,谢谢!!
  • 然后点击答案并标记为已完成(如果已为您完成)
猜你喜欢
  • 2018-10-12
  • 2013-04-24
  • 1970-01-01
  • 1970-01-01
  • 2022-10-21
  • 1970-01-01
  • 2018-02-24
  • 2013-12-06
  • 1970-01-01
相关资源
最近更新 更多