Swift:确保 arrary 中对象的反初始化

Swift: Ensuring deinitialization of objects in arrary

提问人:user4779109 提问时间:11/7/2023 更新时间:11/7/2023 访问量:68

问:

我是 Swift ARC 的新手,我可能遇到以下 swift 代码的内存问题:

class Device {
    let name: String
    var ports: [Port]

    init(name: String, ports: [Port] = []) {
        self.name = name
        self.ports = ports
     }
}


class Port {
    let name: String
    let device: Device

    init(name: String, device: Device) {
        self.name = name
        self.device = device
     }
}

在提供的 Swift 代码中,设备对象包含端口数组,每个端口对象都与特定设备相关联。只要设备的端口存在,它就应该保留在内存中,并且端口的设备永远不应该为零。有时,端口应仅保留在设备的端口数组中,而不应保留任何其他引用。但是使用上面的代码,未使用的实例将永远保留在内存中,并且会越来越多。

我已经测试了以下内容:

1.) 在 Port 类中。这样我就不能再做这样的事情了,因为设备会立即被释放(在视图更改后):weak let device: Device?

let device = Device(name: "name")
let port = Port(name: "port", device: device)

将视图更改为带端口对象的 PortView / 不带设备对象 --> 设备获取已取消初始化。

2.) 弱数组(带有属性包装器)。但是,如果数组中的端口较弱,则当没有其他引用时(逻辑上),它们也会立即被取消初始化 - 但有时故意不引用它们,因此它们必须保留在数组中。

我的思维错误在哪里?

数组 swift 内存 automatic-ref-counting

评论

0赞 Larme 11/7/2023
我会使用一个,但整个逻辑是您需要如何保持对父级(持有 .您还可以使用 struct,或者解释为什么 Port 需要知道其设备?就像在您的示例中一样,您无法从 .Deviceportsdeviceport
0赞 user4779109 11/7/2023
这个例子只是为了以简化的方式说明它,在我的项目中,它有点大,不幸的是,类是必要的(由于继承等)。根据视图(例如 PortView),只应传递相应的端口对象 - 但设备的详细信息也应显示在那里(例如 port.getDevice().getName())。在我的端口类中,还有许多执行 API 调用的方法,这些方法需要相应设备的名称。
1赞 Rob Napier 11/7/2023
“但有时故意不提及它们,所以它们必须留在阵列中。”好的,那么您希望何时解除分配端口和/或设备?听起来你依赖于它们自我保留的事实。在这种情况下,你需要一个明确的“销毁”方法(可以消除所有内容以破坏保留循环)。否则,您需要一些可以固定所有设备或端口的东西。(这不应该是观点;那是暂时的。视图应仅显示 Model 对象的当前状态。它不应该拥有这些数据。
2赞 Rob Napier 11/7/2023
这里没有魔法。由你来决定这些东西何时应该存在(在这种情况下,你需要维护对它们的引用)以及何时不需要它们(在这种情况下,你应该清除对它们的引用)。我怀疑你的错误是你试图让视图保存所有内容,而不是将其拉出到模型中。developer.apple.com/documentation/swiftui/......
0赞 user4779109 11/13/2023
多谢。我以前与内存管理没有太多关系,所以直到现在我才考虑太多。最后,这比我想象的要容易得多。我已经有一个模型,其中阵列通过其端口容纳所有设备。以前,在刷新期间,此阵列只是被新返回的设备覆盖。但是,如果我事先清空所有设备的端口阵列,则所有内容都将正确解除分配。

答: 暂无答案