Hugo Alonso Hugo Alonso - 6 months ago 132
Swift Question

Why is there a memory leak at String creation in swift?

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?

Answer

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.