在结构中存储对象时出现 Swift 问题

标签 swift memory-management struct

我对这里的内存管理方式感到困惑,假设有一个场景:

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

如果我查看内存映射:

enter image description here

保留周期

在这种情况下我如何管理内存

最佳答案

首先,您应该非常非常小心地将引用类型放在值类型中,尤其是对外界可见的可变引用类型。结构始终是值类型,但您还希望它们具有值语义,并且在包含引用类型时做到这一点具有挑战性。 (这是很有可能的,很多 stdlib 类型都这样做是为了实现写时复制;这只是具有挑战性。)

所以简短的版本是“你几乎肯定不想做你在这里做的事。”

但是如果您在 SomeStruct 中维护了值语义,那么答案就是复制一份。制作值类型的副本总是没问题的。

someStruct.closure = { [someStruct] in
    print(someStruct)
}

这为闭包提供了它自己的不可变值,该值是 someStruct 的副本。 someStruct 的 future 更改不会影响此关闭。

如果您的意思是将来对 someStruct 的更改会影响此闭包,那么您可能违反了值语义,您应该重新设计(可能通过使 SomeStruct 成为一个类,如果你的意思是它具有引用语义)。

关于在结构中存储对象时出现 Swift 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58594001/

相关文章:

ios - 如何在 Swift 中使用带有 #define 宏的 Objective-C 代码

ios - 如何设置一个整数值作为导航栏的标题?

c++ - 如何使用 delete [] 运算符清除动态分配的内存? (无法使用常规删除语法清除)

c++ - 用于存储和访问结构指针的正确 Qt 数据结构

ios - 如何将自定义 tableViewController 嵌入到其他 viewController

ios - 无法关闭我从 SKScene 调用的 MFMailComposeViewController

c# - 检测何时即将耗尽内存(获取 "free physical memory"的数量)

java - 静态成员驻留在内存中的什么地方,是永久代吗?

c - strtol帮助为什么它返回0

c - 如何从链表中删除节点