斯威夫特方便初始化扩展SKPhysicsBody
问题描述:
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相同的根本问题: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。)
你是怎么调用初始化程序的? – Cristik
'redBox.physicsBody = SKPhysicsBody(rectangleOfSize:redBox.frame.size,withAnchorPoint:redBox.anchorPoint)' –
我当前的解决方法是使用工厂方法'SKPhysicsBody.bodyWithRectangleOfSize(:withAnchorPoint:)'返回物理主体。这完全感觉不到迅捷,因为所有的obj-c工厂都很好地映射到各自的init方法。 –