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.)