You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中使用onDisappear修饰符识别被销毁的View并同步数据源

核心问题定位

    1. 删除逻辑错误:你当前在onDisappear中调用customModel.array.remove(at: id)是按索引删除元素,但customModel.array存储的是id值的集合,id值和数组索引没有绑定关系,删除非末尾元素时必然会删错数据。
    1. PreferenceKey实现逻辑错误:当前的IntPreferenceKey返回值为单个Int,reduce方法只会保留最后一个CustomView的id,其余CustomView的id无法被正常识别添加到副本数组。

修复代码

你无需修改原始数据源所在的ContentView,只需要调整CustomView、CustomModel的实现即可,修复后可以完全满足同步要求:

struct CustomView<Content: View>: View {
    let id: Int
    let content: () -> Content
    @StateObject private var customModel: CustomModel = CustomModel.shared
    
    var body: some View {
        content()
            .onAppear {
                // 视图出现时添加对应id到副本数组
                if !customModel.array.contains(id) {
                    customModel.array.append(id)
                }
            }
            .onDisappear {
                // 视图消失时删除对应id值的元素,而非按索引删除
                customModel.array.removeAll { $0 == id }
                print("id:", id, "is removed!")
            }
    }
}

class CustomModel: ObservableObject {
    static let shared: CustomModel = CustomModel()
    @Published var array: [Int] = [] {
        didSet {
            // 按原始数组顺序输出,保证和原始数据源展示一致
            print(array.sorted())
        }
    }
}

实现说明

  • 用onAppear代替原来的PreferenceKey逻辑,每个视图加载时主动上报自身id,逻辑更直观可控
  • 删除逻辑改为匹配id值删除,不再依赖索引,避免删错数据
  • 全程不需要向CustomView传递原始数据源,也不需要任何通知机制,原始数据源无任何适配改动
  • 副本数组会和原始数据源的元素完全同步,增删操作都会实时响应

内容的提问来源于stack exchange,提问作者swiftPunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 21:27:03