能否让SKSpriteNode的初始化失败但不引发应用崩溃?
问题解答
首先明确核心结论:不存在类似返回-1的特殊返回值来终止实例创建,有两种合法的实现方案,优先推荐提前判断的方案。
方案1:创建实例前完成条件判断(最优选择)
这是性能最好、逻辑最清晰的实现方式,完全没有多余的初始化开销,不会产生无效的内存占用。你只需要在for循环调用初始化方法前,先校验是否满足创建条件,符合条件再执行初始化,不符合直接跳过当前循环即可。
示例代码:
for i in 0..<slotCount { // 提前做条件判断,只有满足要求才创建实例 guard 满足你的特定条件 else { continue } let slot = GuessSlot(color: .clear, size: slotSize, width: slotWidth, iFactor: i, guessBarRef: bar) // 其他后续逻辑 }
方案2:把自定义初始化改为可失败初始化
Swift支持可失败初始化器,用init?声明,当不满足创建条件时可以直接返回nil,不会生成实例也不会导致崩溃。
注意要遵循Swift的初始化规则:返回nil前必须完成所有非可选存储属性的赋值。修改后的GuessSlot初始化示例如下:
class GuessSlot : SKSpriteNode{ var nodeIndex : Int var holdingGem : Bool = false // 改成可失败初始化器 init?(color: SKColor, size: CGSize, width: CGFloat, iFactor: Int, guessBarRef: GuessBar){ self.nodeIndex = iFactor // 这里加你的特定判断条件,不满足直接返回nil guard 满足你的创建条件 else { return nil } let skTexture = SKTexture(imageNamed: "gem_slot") super.init(texture: skTexture, color: color, size: size) self.name = "slot" self.size.width = size.width self.size.height = size.width self.anchorPoint = CGPoint(x: 0.5, y: 0.5) var indexSpacing = (size.width * CGFloat(iFactor)) + ((size.height * 2) * CGFloat(iFactor)) + (size.width/2) indexSpacing += 10 self.position = CGPoint(x: indexSpacing, y: guessBarRef.size.height/2) self.isHidden = false guessBarRef.addChild(self) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
调用时需要解包判断:
for i in 0..<slotCount { if let slot = GuessSlot(color: .clear, size: slotSize, width: slotWidth, iFactor: i, guessBarRef: bar) { // 初始化成功的后续逻辑 } }
额外优化建议
当前初始化方法内部直接调用guessBarRef.addChild(self)的设计耦合性较高,建议把添加节点的逻辑移到外部,初始化完成后再手动添加,避免后续逻辑调整时出现内存泄露或者节点异常挂载的问题。
内容的提问来源于stack exchange,提问作者LuisC329
相关产品推荐
相关产品推荐

