子类化SCNNode使用MDLObject非指定初始化器报错,该如何解决?
解决SCNNode子类化使用MDLObject初始化的问题
你遇到的错误本质是Swift初始化规则的限制:子类的指定初始化器必须调用父类的指定初始化器,而SCNNode.init(mdlObject:)是父类的便利初始化器,不能被子类的指定初始化器直接调用。
下面提供两种可行的解决方案:
方案一:将自定义初始化器改为便利初始化器
把init(model:)标记为convenience(便利初始化器),这样就可以合法调用父类的便利初始化器,同时保留你的自定义逻辑:
public class MyModelNode: SCNNode { public var geo: SCNGeometry! private func dfs(node: SCNNode) { if let geometry = node.geometry { geo = geometry return } for child in node.childNodes { dfs(node: child) } } // 标记为便利初始化器 convenience public init(model: MDLObject) { // 调用父类的便利初始化器加载模型 self.init(mdlObject: model) // 执行自定义的几何查找逻辑 dfs(node: self) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
方案二:使用指定初始化器+手动设置模型
保持自定义初始化器为指定初始化器,先调用父类的指定初始化器init(),再通过setMDLObject(_:)方法加载模型对象,完全符合Swift初始化链规则:
public class MyModelNode: SCNNode { public var geo: SCNGeometry! private func dfs(node: SCNNode) { if let geometry = node.geometry { geo = geometry return } for child in node.childNodes { dfs(node: child) } } public init(model: MDLObject) { // 先调用父类的指定初始化器 super.init() // 手动将MDLObject应用到节点 self.setMDLObject(model) // 执行自定义的几何查找逻辑 dfs(node: self) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
两种方案都能实现你的需求:方案一更简洁,直接复用父类的初始化逻辑;方案二更严谨,明确遵循指定初始化器的调用规则,避免依赖父类便利初始化器的继承特性。
内容的提问来源于stack exchange,提问作者OMGPOP
相关产品推荐
相关产品推荐

