当前位置 : 主页 > 手机开发 > 其它 >

SKPhysicsBody的Swift便利初始化程序扩展

来源:互联网 收集:自由互联 发布时间:2021-06-11
extension SKPhysicsBody { /// anchorPoint version of init(rectangleOfSize:center:) convenience init(rectangleOfSize s: CGSize, withAnchorPoint anchorPoint: CGPoint) { var center = CGPoint() center.x = (s.width / 2) - ( s.width * anchorPoint
extension SKPhysicsBody {

    /// anchorPoint version of init(rectangleOfSize:center:)
    convenience init(rectangleOfSize s: CGSize, withAnchorPoint anchorPoint: CGPoint) {
        var center = CGPoint()
        center.x = (s.width / 2) - ( s.width * anchorPoint.x)
        center.y = (s.height / 2 ) - ( s.height * anchorPoint.y)
        self.init(rectangleOfSize: s, center: center)
    }

}

我在运行时遇到了这个错误

-[PKPhysicsBody initWithRectangleOfSize:withAnchorPoint:]: unrecognized selector sent to instance 0x7f9b03c4fff0

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PKPhysicsBody initWithRectangleOfSize:withAnchorPoint:]: unrecognized selector sent to instance 0x7f9b03c4fff0'

这是我在代码中调用的方式

// redBox is a typical SKSpriteNode()
redBox.physicsBody = SKPhysicsBody(rectangleOfSize: redBox.frame.size, withAnchorPoint: redBox.anchorPoint)

我基本上想扩展SKPhysicsBody类,为其工厂方法提供方便的初始化程序

正如@Cristik在评论中所猜测的那样,这与 this question和 this question一样是根本问题:公共SKPhysicsBody类是提供其实现的私有PKPhysicsBody类的便利接口.

在过去,这种方法在很大程度上依赖于Objective-C的“duck typing”行为 – 只要ClassA响应所有与ClassB相同的选择器,就可以在指针上调用任何这些选择器,这些指针的静态类型(向编译器声明的类型)在源代码中)是ClassB,即使运行时的实际对象实际上是ClassA的实例.

Swift对运行时类型的正确性比ObjC更严格,因此单独“鸭子打字”是不够的.从iOS 9 / OS X 10.11开始,SpriteKit有一些解决方法可以让PKPhysicsBody实例更好地伪装成SKPhysicsBody实例.

但是那些并没有涵盖所有情况 – 特别是它没有捕获(ObjC)[SKPhysicsBody alloc]返回PKPhysicsBody实例,这意味着任何在Swift中向SKPhysicsBody添加初始化器的尝试都将失败. (因为ObjC alloc / init进程在Swift中减少为一个初始化程序调用.)

我认为这是一个错误并推荐filing it with Apple.

编辑/更新:直到该错误得到修复(现在已经过了一年),解决方法是将方便的“初始化程序”改为类方法. (如果你必须,还是全球功能,但…… ewww.)

网友评论