Andrius Steponavičius
Andrius Steponavičius

Reputation: 8184

Swift issue when storing Object inside a struct

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:

enter image description here

retain cycle

How do I manage memory in this case

Upvotes: 0

Views: 184

Answers (1)

Rob Napier
Rob Napier

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

Related Questions