简短的答案
- 编译器使用不同的过程来分析代码。有很多关于大学编译器如何工作的讲座。所以很难给你一个正确的答案。
- 使用你需要的东西。很难估计这要花多少钱。@escaping 和 @no-escaping 有不同的用例。
- 我没有看到缺点。使用弱是防止零售周期和内存泄漏的好方法。
解释
1:所以这个编译器究竟是如何工作的,我真的不知道。但是,如果您想了解编译器通常是如何工作的,请阅读一些像这样的轻量级文章
在我的想法中,编译器将进行词法分析、语法分析和语义分析。所以编译器会检测你是否需要转义。
2:闭包是 swift 中的一个概念,即您“在事情完成后做事”。有关更多详细信息,请查看文档和此处
以下信息大量基于本文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分开
受帖子示例的启发,可以在其范围之外访问局部变量的内存吗?
你租了一个旅馆房间。您第二天早上退房,锁上门,但“忘记”归还您的钥匙。你偷了钥匙!没有备用钥匙。所以酒店房间是锁着的。酒店老板不能再租这个房间了。现在有很多客人偷钥匙。有时每个房间实际上都是免费的,但上锁了。
有点幻想,租户是一个关闭。他租用房间(创建对房间实例的引用)。他睡在那里(异步操作)。他应该归还他的钥匙,但他没有。
据我了解,闭包不拥有该对象。它是闭包和实例属性之间的引用。
苹果文档:
如果您将闭包分配给类实例的属性,并且该闭包的主体捕获该实例,也会发生强引用循环。这种捕获可能是因为闭包的主体访问了实例的属性,例如 self.someProperty,或者因为闭包调用了实例上的方法,例如 self.someMethod()。在任何一种情况下,这些访问都会导致闭包“捕获”自我,从而创建一个强引用循环。
weak
您可以使用或解决该强循环unowned
。weak
在我看来,苹果用来解释和之间区别的图像unowned
非常好:请参阅自动引用计数