为什么在迅速创建String时会发生内存泄漏?

为什么在迅速创建String时会发生内存泄漏?

问题描述:

泄漏是根泄漏,在同一行中多次引起该图像,但在下面还存在另一次称为单次泄漏,并且还会产生泄漏.

The Leak is a Root Leak, In this image is being caused several times on the same line, but there is another below that is called single time and also produces a leak.

这是调用堆栈,位于之后,调用之前声明的代码行.

This is the call stack after calling the line of code stated before.

这是仪器查找泄漏所在的类:

This is the class where the leak is located by 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 更改为:

Leak is detected at line of computed variable description containing return "(\(id)) \(name)" and it gets solved after changing description into:

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总是成功".

The last one emits a "Conditional cast from 'String!' to String always succeeds".

所以,即使这看起来像是黑客.

So, even this looks like a hack.

为什么会导致泄漏?

我测试了您的代码,并经过了几个线程,我的理解是,在使用字符串插值而不是使用可选变量时,必须具有可选的绑定if let子句.直接地.对于字符串连接,如果我们直接使用可选选项,则没有问题.问题在于插值.

I tested your code and gone through few threads and my understanding is that you have to optional binding if let clause, when using string interpolation instead of using optional variables directly. For String concatenation, if we use optionals directly there is no problem. The problem is with interpolation.

var description: String {
    if let id = self.id, let name = self.name {
        return "(\(id)) \(name)"
    }
    return "NO AVAILABLE DESCRIPTION"
}

您可以在此处获得更多信息 Swift String插值中的内存泄漏. 似乎是一个错误,可能会在将来的版本中予以解决.

You may get more info here memory leak in Swift String interpolation. Seems like a bug and may be in future release it will be solved.