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

时间:2016-01-20 08:16:55

标签: swift sprite-kit swift-extensions

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类,为其工厂方法

提供方便的初始化程序

1 个答案:

答案 0 :(得分:7)

正如@Cristik在评论中所猜测的那样,这与this questionthis question的根本问题相同:公共SKPhysicsBody类是私有PKPhysicsBody的便捷界面提供实现的类。

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

Swift对运行时类型的正确性比ObjC更严格,所以" duck typing"仅靠还不够。从iOS 9 / OS X 10.11开始,SpriteKit有一些变通方法可以让PKPhysicsBody个实例更好地伪装成SKPhysicsBody个实例。

但是那些并不涵盖所有情况 - 特别是它没有捕获(ObjC)[SKPhysicsBody alloc]返回PKPhysicsBody实例,这意味着任何尝试向{添加初始化器的尝试Swift中的{1}}会失败。 (因为ObjC SKPhysicsBody / alloc进程在Swift中被简化为一个初始化程序调用。)

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

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