Swift开发中同一数组被多函数调用时如何实现自动清空的最优方案
问题原因分析
你尝试的计算属性+didSet写法存在两个核心错误:
didSet是存储属性专属的观察器,不能用在计算属性上,这段代码本身无法通过编译。- 即便你给存储属性添加didSet并在内部调用
removeAll(),逻辑也完全不符合需求:didSet会在数组被修改后触发,会直接清空你刚写入数组的内容。
可选实现方案
下面给三个不同适用场景的解决方案,按推荐优先级排序:
方案1:统一在触发入口清空(最推荐)
你的三个函数都是通过 segmented control 点击触发,直接在点击事件的上游统一执行清空逻辑即可,所有业务函数不需要做任何修改:
// segmented control 点击回调 @objc func segmentValueChanged(_ sender: UISegmentedControl) { // 统一前置清空数组 array.removeAll() // 再调用对应业务函数 switch sender.selectedSegmentIndex { case 0: firstFunction() case 1: secondFunction() case 2: thirdFunction() default: break } } // 业务函数内不需要再写清空代码 func firstFunction() { // 直接使用array即可,已经是空的 }
优势:仅需编写1次清空逻辑,和业务代码完全解耦,维护成本最低。
方案2:抽取公共清空方法
如果三个函数还有其他调用场景,不只是从segment点击触发,可以把清空逻辑抽成独立方法,替换原来的array = []:
func resetChartArray() { array.removeAll() } func firstFunction() { resetChartArray() // 后续业务逻辑 } func secondFunction() { resetChartArray() // 后续业务逻辑 }
优势:后续如果要修改清空逻辑(比如加日志、判空等),只需要修改resetChartArray一处即可,不用逐个修改所有业务函数。
方案3:属性包装器强制自动清空
如果你需要从语法层面保证,不管任何场景调用数组前一定会清空,不会漏写清空代码,可以使用属性包装器实现:
@propertyWrapper struct AutoResetBeforeUse<Value> { private var value: Value private let resetValue: Value init(wrappedValue: Value, resetValue: Value) { self.value = wrappedValue self.resetValue = resetValue } var wrappedValue: Value { mutating get { // 每次读取数组前先清空 value = resetValue return value } set { value = newValue } } } // 定义数组 @AutoResetBeforeUse(resetValue: []) var array: [ChartData] = [] // 业务函数内直接使用即可,每次读取会自动清空 func firstFunction() { // 第一次访问array时已经自动清空 array.append(...) }
优势:完全不用手动调用清空逻辑,自动实现需求。
内容的提问来源于stack exchange,提问作者TeddyKen
相关产品推荐
相关产品推荐

