Why is there a memory leak at String creation in s

2019-03-17 13:19发布

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.

enter image description here

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

enter image description here

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)"
 }
}

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
}

Update:

or

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

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

So, even this looks like a hack.

Why is this causing a leak?

2条回答
Fickle 薄情
2楼-- · 2019-03-17 13:46

I actually prefer the solution that Hugo posted along with his question because the code looks cleaner. After profiling my own code, I also found that my memory leak was resolved after using string concatenation:

var description: String {
    return "(" + id + ") " + name
}

For what it's worth, this post (http://www.globalnerdy.com/2016/02/03/concatenating-strings-in-swift-which-way-is-faster/) also says that using string concatenation in Swift is significantly faster.

查看更多
Fickle 薄情
3楼-- · 2019-03-17 14:04

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"
}

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.

查看更多
登录 后发表回答