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

Swift中如何在数组完全初始化后执行指定函数?

解决数组完全初始化后仅执行一次函数的问题

你遇到的问题很典型——didSet会在数组的每次修改(包括添加、移除、替换元素)时触发,而你想要的是在数组完全初始化完毕后只执行一次目标操作。下面给你几个适配不同场景的解决方案:

场景1:数组是静态固定初始化(如你代码里的直接赋值)

如果你的数组是像示例里那样直接用固定值初始化的,那最简单的方式就是在数组声明后单独调用一次目标函数——因为didSet在数组初始化赋值的时候不会被触发,只有后续修改才会触发:

var arrayScore = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

// 把初始化后要执行的逻辑封装成函数
func setupAfterArrayInit() {
    for i in 0..<arrayScore.count {
        UserDefaults.standard.set(Int(arrayScore[i]), forKey: "arrayScore\(i)")
    }
    LineGraphView.setNeedsDisplay()
}

// 在合适的时机调用(比如viewDidLoad里,或者数组声明后的代码块)
setupAfterArrayInit()

这样既保证了初始化完成后只执行一次,又避免了后续修改数组时重复触发操作。

场景2:数组是动态逐步初始化(比如从网络/数据库加载元素)

如果你的数组是通过多次添加元素完成初始化的(比如循环添加、异步加载后拼接),可以用一个标志位来控制是否已经完成初始化,只有在初始化完成后才执行操作:

var arrayScore = [Double]()
private var isArrayInitialized = false

// 封装添加元素的方法,统一控制初始化完成逻辑
func addScore(_ score: Double) {
    arrayScore.append(score)
    // 这里根据你的实际需求判断初始化完成条件,比如达到指定长度
    if arrayScore.count == 7 && !isArrayInitialized {
        isArrayInitialized = true
        // 执行初始化完成后的操作
        for i in 0..<arrayScore.count {
            UserDefaults.standard.set(Int(arrayScore[i]), forKey: "arrayScore\(i)")
        }
        LineGraphView.setNeedsDisplay()
    }
}

// 使用示例:逐步添加元素,直到满足条件才触发操作
addScore(0.0)
addScore(0.0)
// ...继续添加直到满7个元素

或者如果你是用批量赋值的方式完成初始化,也可以在didSet里结合标志位判断:

private var isArrayInitialized = false
var arrayScore = [Double]() {
    didSet {
        // 仅在首次完成初始化时执行操作
        guard !isArrayInitialized else { return }
        // 额外判断数组是否符合初始化完成的状态(比如长度正确)
        if arrayScore.count == 7 {
            isArrayInitialized = true
            for i in 0..<arrayScore.count {
                UserDefaults.standard.set(Int(arrayScore[i]), forKey: "arrayScore\(i)")
            }
            LineGraphView.setNeedsDisplay()
        }
    }
}

// 初始化时直接批量赋值
arrayScore = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

额外优化思路:用自定义类包装数组

如果你不想手动管理标志位,也可以把数组包装成一个自定义类,在类的初始化方法里完成后续操作,这样更符合面向对象的设计逻辑:

class ScoreArray {
    var scores: [Double]
    init(scores: [Double]) {
        self.scores = scores
        // 初始化完成后直接执行操作
        for i in 0..<scores.count {
            UserDefaults.standard.set(Int(scores[i]), forKey: "arrayScore\(i)")
        }
        LineGraphView.setNeedsDisplay()
    }
}

// 使用时直接初始化即可
let arrayScore = ScoreArray(scores: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])

这样就能确保操作只在数组完全初始化时执行一次,后续修改scores数组时也不会触发重复操作(如果需要后续修改时触发,再给scores添加didSet即可)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:26:31