我对这里的内存管理方式感到困惑,假设有一个场景:
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")
我期望的是:
Optional(test.SomeStruct(object: test.SomeObject, closure: Optional((Function))))
deinitCalled
the end
但是我得到的是这样的:
SomeStruct(object: test.SomeObject, closure: Optional((Function)))
the end
如果我查看内存映射:
保留周期
在这种情况下我如何管理内存
最佳答案
首先,您应该非常非常小心地将引用类型放在值类型中,尤其是对外界可见的可变引用类型。结构始终是值类型,但您还希望它们具有值语义,并且在包含引用类型时做到这一点具有挑战性。 (这是很有可能的,很多 stdlib 类型都这样做是为了实现写时复制;这只是具有挑战性。)
所以简短的版本是“你几乎肯定不想做你在这里做的事。”
但是如果您在 SomeStruct 中维护了值语义,那么答案就是复制一份。制作值类型的副本总是没问题的。
someStruct.closure = { [someStruct] in
print(someStruct)
}
这为闭包提供了它自己的不可变值,该值是 someStruct
的副本。 someStruct
的 future 更改不会影响此关闭。
如果您的意思是将来对 someStruct
的更改会影响此闭包,那么您可能违反了值语义,您应该重新设计(可能通过使 SomeStruct 成为一个类,如果你的意思是它具有引用语义)。
关于在结构中存储对象时出现 Swift 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58594001/