下面的代码给出了一个错误-它似乎物理连接数组有类PKPhysicsJoint。有人知道我怎么能在斯威夫特的关节里迭代吗?
文档确实说physicsBody.joints应该返回一个SKPhysicsJoint数组。
import SpriteKit
let scene = SKScene(size: CGSize(width: 200, height: 200))
let nodeA = SKNode()
let nodeB = SKNode()
nodeA.physicsBody = SKPhysicsBody(circleOfRadius: 20)
nodeB.physicsBody = SKPhysicsBody(circleOfRadius: 20)
scene.addChild(nodeA)
scene.addChild(nodeB)
let joint = SKPhysicsJointFixed.jointWithBodyA(nodeA.physicsBody, bodyB: nodeB.physicsBody, anchor: CGPointZero)
scene.physicsWorld.addJoint(joint)
for joint in nodeA.physicsBody!.joints as [SKPhysicsJoint] {
// do something else here
}给出错误:
Execution was interrupted. reason: EXC_BAD_INSTRUCTION...发布于 2015-02-13 18:08:52
Update:这是一个bug,它在iOS 9/OSX10.11中得到了修正--问题中的代码现在才起作用。
为后世/使用旧SDK/等的人留下原答案。
这看起来像一个bug - 你应该把它归档。很难说它是SpriteKit bug还是Swift bug,但这是苹果的问题,而不是你的问题。:)
如果将代码粘贴到操场中,问题很明显-- joint实际上是幕后的PKPhysicsJointWeld。这是一些应该是实现细节的内部类。在ObjC中,这是没有问题的,因为C中的转换只是告诉编译器:“相信我,这个指针实际上是一个SKPhysicsJoint,所以让我将物理联合方法(以及其他任何方法)称为它,没有人会更聪明”。Swift中的类型转换要求在类型之间存在类型层次关系,而PKPhysicsJointWeld不是SKPhysicsJoint的子类型/子类,因此转换失败。
您可以通过避免强制转换到[SKPhysicsJoint]来解决此问题。
for joint in nodeA.physicsBody!.joints {
// do something else here
}这样,您就失去了某种类型安全性-- joint是一个AnyObject,因此像ObjC的id类型一样,编译器允许您调用它上的任何方法。(如果对象不实现该方法,则可能在运行时失败。)但至少它还在运行。
另一个解决方法是:在循环中,您可以将joint转换为SKPhysicsJoint。但是,由于该转换跨类型层次结构,所以必须使用unsafeBitCast
for joint in nodeA.physicsBody!.joints {
let skJoint = unsafeBitCast(joint, SKPhysicsJoint.self)
// do stuff with skJoint
}这会让您返回一点编译时类型“安全”,因为此后编译器将要求您对skJoint所做的任何操作都与SKPhysicsJoint兼容,但它在本质上仍然是不安全的,因为它依赖于运行时类型的某些挥手,而这些类型可能并不总是有效。您必须再次使用unsafeBitCast来获得一个特定的联合子类,而不知道它可能是哪个子类。(再一次,现在是提交bug的好时机。.)
(您可能在粘贴到操场时注意到,physicsWorld也属于内部类:PKPhysicsWorld。那为什么不也失败呢?当您使用physicsWorld属性时,所有类型转换都发生在ObjC端,Swift信任ObjC告诉它的任何内容。但是,在处理joints数组时,您必须在Swift端执行类型强制转换,而且Swift对类型检查要严格得多。)
https://stackoverflow.com/questions/28501832
复制相似问题