Swift自定义SceneKit扩展与未来系统API冲突时应用是否会崩溃?
问题解答
首先明确:不会导致运行崩溃,但会触发编译错误。
原因
Swift在编译阶段就会检测到同一类型(这里是SCNNode)的扩展中存在同名成员(spatialEulerAngles)的冲突,直接抛出「ambiguous use of 'spatialEulerAngles'」的编译错误,根本到不了运行环节,所以不会崩溃。
如何提前规避这个问题
- 给自定义成员加专属前缀:比如把属性名改成
mySpatialEulerAngles或者用你的项目/模块缩写当前缀,比如APP_SpatialEulerAngles,从根源避免和官方未来的命名撞车。 - 用模块名限定访问:如果你的代码是在自定义模块中(不是主App模块),可以通过模块名来区分自己的扩展成员,比如
MyCustomModule.SCNNode.spatialEulerAngles,不过这种写法稍显繁琐。 - 改用协议扩展封装:定义一个专属协议,把自定义属性放在协议扩展里,通过协议约束来访问,比如:
这样即使官方后来给import SceneKit import Spatial protocol SpatialNode {} extension SCNNode: SpatialNode {} extension SpatialNode where Self: SCNNode { var spatialEulerAngles: EulerAngles { get { return EulerAngles(angles: [eulerAngles.x, eulerAngles.y, eulerAngles.z], order: .xyz) } set { eulerAngles = SCNVector3(x: newValue.angles.x, y: newValue.angles.y, z: newValue.angles.z) } } }SCNNode加了同名属性,你通过SpatialNode协议访问的还是自己实现的版本,不会冲突。
总结
未来如果Apple真的引入了同名扩展成员,你只需要在编译阶段修改自己的代码(比如重命名属性)就能解决,完全不用担心运行崩溃的问题。
内容的提问来源于stack exchange,提问作者OMGPOP
相关产品推荐
相关产品推荐

