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
相关产品推荐
相关产品推荐

