Reputation: 6824
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)"
}
}
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?
Upvotes: 28
Views: 7363
Reputation: 3000
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.
Upvotes: 13