为啥在 swift 中创建字符串时会出现内存泄漏?
Posted
技术标签:
【中文标题】为啥在 swift 中创建字符串时会出现内存泄漏?【英文标题】:Why is there a memory leak at String creation in swift?为什么在 swift 中创建字符串时会出现内存泄漏? 【发布时间】:2015-07-14 08:58:43 【问题描述】:泄漏是Root Leak,在这张图片中,同一行发生了多次,但下面还有一个称为单次泄漏,也会产生泄漏。
这是调用栈之后调用前面所述的代码行。
这是 Instruments 定位泄漏的类:
class Item
var id: String!
var name: String!
internal init(name: String)
self.name = name
self.id = name
var description: String
return "(\(id)) \(name)"
在包含return "(\(id)) \(name)"
的计算变量description 行检测到泄漏,并将description 更改为:
var description: String
return "(" + id + ") " + name
更新:
或
var description: String
if let id = self.id as? String, let name = self.name as? String
return "(\(id)) \(name)"
return "NO AVAILABLE DESCRIPTION"
最后一个发出“来自'String!'的条件转换! to String 总是成功”。
所以,即使这看起来像是一个 hack。
为什么会导致泄漏?
【问题讨论】:
很可能是这个类之外的东西导致了泄漏。检查创建此 Item 对象的类。它是引用 id 还是 name?另外,泄漏是一个“循环”吗?这也表明这个类之外的东西正在持有对它的引用。 @Stephen 我已经更新了问题,添加了一些关于泄漏的见解 两种形式的字符串连接都应该是有效的。看起来这可能是苹果的错误。您可以尝试向 Apple 提交错误报告。 【参考方案1】:我测试了你的代码并经历了几个线程,我的理解是,当使用字符串插值而不是直接使用可选变量时,你必须可选绑定if let
子句。对于字符串连接,如果我们直接使用可选项是没有问题的。问题在于插值。
var description: String
if let id = self.id, let name = self.name
return "(\(id)) \(name)"
return "NO AVAILABLE DESCRIPTION"
您可以在这里memory leak in Swift String interpolation 获得更多信息。 似乎是一个错误,可能会在未来的版本中得到解决。
【讨论】:
此内存泄漏,如果我使用多个可选变量,我会发生插值,其中一个效果很好。 我尝试了你的代码,即使我的班级变量id
和 name
是 String!
并且 Xcode 声明“来自'字符串的条件转换!' to String 总是成功”它编译并停止抛出这样的泄漏。
我在这里测试过,我也得到了同样的结果。
我将您的提示添加到主要问题中以获得更好的可见性,如果没有人可以给我一个更好的答案 “为什么?” 这正在发生,那么正确的答案将是分配给你。由于我会假设存在错误,遗憾的是我自己无法提交这样的错误报告。
如果你想检查它的状态,这里有一个类似问题的错误报告bugs.swift.org。以上是关于为啥在 swift 中创建字符串时会出现内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章