Reputation: 8184
I am confused of how memory is managed here, lets say there is a scenario:
import Foundation
class SomeObject {
deinit {
print("deinitCalled")
}
}
struct SomeStruct {
let object = SomeObject()
var closure: (() -> Void)?
}
func someFunction() {
var someStruct = SomeStruct()
someStruct.closure = {
print(someStruct)
}
someStruct.closure?()
}
someFunction()
print("the end")
What I would expect here is:
Optional(test.SomeStruct(object: test.SomeObject, closure: Optional((Function))))
deinitCalled
the end
However what I get is this:
SomeStruct(object: test.SomeObject, closure: Optional((Function)))
the end
And if I look at memory map:
retain cycle
How do I manage memory in this case
Upvotes: 0
Views: 184
Reputation: 299345
First, you should be very, very careful about putting reference types inside of value types, and especially a mutable reference type that is visible to the outside world. Structs are always value types, but you also want them to have value semantics, and it's challenging to do that while containing reference types. (It's very possible, lots of stdlib types do it in order to implement copy-on-write; it's just challenging.)
So the short version is "you almost certainly don't want to do what you're doing here."
But if you have maintained value semantics in SomeStruct, then the answer is to just make a copy. It's always fine to make a copy of a value type.
someStruct.closure = { [someStruct] in
print(someStruct)
}
This gives the closure it's own immutable value that is a copy of someStruct
. Future changes to someStruct
won't impact this closure.
If you mean for future changes to someStruct
to impact this closure, then you may be violating value semantics, and you should redesign (likely by making SomeStruct a class, if you mean it to have reference semantics).
Upvotes: 4