swift - 将对象存储在结构中时出现 Swift 问题
问题描述
我对这里的内存管理方式感到困惑,假设有一个场景:
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
不会影响此关闭。
如果您的意思是未来的更改会someStruct
影响此闭包,那么您可能违反了值语义,您应该重新设计(可能通过使 SomeStruct 成为一个类,如果您的意思是它具有引用语义)。
推荐阅读
- php - 无法根据 MySQL 数据在 Google Chart 中创建基线
- python - 使用函数对象作为 numba njit 函数的参数
- c# - 如何减少此程序中使用的 C# 代码量?
- css - 在反应形式中,无法输入文本字段或单击或悬停在按钮上
- node.js - 如何以高质量更改谷歌服务帐户个人资料图片?
- express - 命令性地运行 oneOf 验证?
- python - Amazon Lex 回退功能到 Amazon Alexa 或 Google 协助
- r - 有没有办法在单个日期时间列中查找时差,按 ID 分组?
- django - get_absolute_url 创建空白链接
- node.js - 某些应用程序的 pm2 计划重新加载