2016-01-20 30 views
3
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) 
    } 

} 

我上运行斯威夫特方便初始化扩展SKPhysicsBody

-[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类,以提供一个方便初始值化程序到它的工厂方法

+0

你是怎么调用初始化程序的? – Cristik

+0

'redBox.physicsBody = SKPhysicsBody(rectangleOfSize:redBox.frame.size,withAnchorPoint:redBox.anchorPoint)' –

+0

我当前的解决方法是使用工厂方法'SKPhysicsBody.bodyWithRectangleOfSize(:withAnchorPoint:)'返回物理主体。这完全感觉不到迅捷,因为所有的obj-c工厂都很好地映射到各自的init方法。 –

回答

7

作为@Cristik在评论中猜到了,这个是与this questionthis question相同的根本问题:public SKPhysicsBody类是提供其实现的专用PKPhysicsBody类的便利接口。

在过去,这种做法严重依赖的Objective-C的"duck typing"行为 - 只要ClassA响应都是一样的选择为ClassB,你可以调用任何这些选择的一个指针,其静态类型(类型在源代码中向编译器声明)为ClassB,即使运行时的实际对象实际上是ClassA的实例。

与ObjC相比,Swift对运行时类型的正确性要求更严格,因此仅靠“鸭子打字”是不够的。从iOS 9/OS X 10.11开始,SpriteKit有一些解决方法,允许PKPhysicsBody实例更好地假装为SKPhysicsBody实例。

但是,这些并不包括所有的情况下 - 特别是,它并没有赶上(ObjC)[SKPhysicsBody alloc]返回PKPhysicsBody情况下,这意味着任何试图初始化在斯威夫特添加到SKPhysicsBody将失败。 (因为ObjC alloc/init进程在Swift中减少为一个初始化程序调用。)

我认为这是一个错误并建议filing it with Apple


编辑/更新:而直到这个bug被固定的(它已经过了一年,现在某些产品),解决办法就是让你方便“初始化”到一个类方法来代替。 (或者,如果你必须的话,一个全局函数,但是... ewww。)