Ken*_*iau 3 sprite-kit swift 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)
}
}
Run Code Online (Sandbox Code Playgroud)
我在运行时遇到了这个错误
-[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'
Run Code Online (Sandbox Code Playgroud)
这是我在代码中调用的方式
// redBox is a typical SKSpriteNode()
redBox.physicsBody = SKPhysicsBody(rectangleOfSize: redBox.frame.size, withAnchorPoint: redBox.anchorPoint)
Run Code Online (Sandbox Code Playgroud)
我基本上想扩展SKPhysicsBody类,为其工厂方法提供一个方便的初始化程序
作为@Cristik在评论中猜到了,这是同根生的问题,因为这个问题和这个问题:大众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实例,这意味着SKPhysicsBody在Swift中添加初始化器的任何尝试都将失败.(因为ObjC alloc/ init进程在Swift中被简化为一个初始化程序调用.)
我认为这是一个错误,并建议向Apple提交.
编辑/更新:直到该错误得到修复(现在已经过了一年),解决方法是将方便的"初始化程序"改为类方法.(如果你必须,还是全球功能,但...... ewww.)