1

次のコードではエラーが発生します。物理ジョイント配列にクラス PKPhysicsJoint があるようです。Swift でジョイントを反復処理する方法を知っている人はいますか?

ドキュメントには、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...
4

1 に答える 1

3

更新: これバグであり、iOS 9 / OS X 10.11 で修正されました — 問題のコードは現在動作します。

後世/古いSDKを使用している人々/などのために、元の回答テキストを残します。


これはバグのようです — 報告する必要があります。これを SpriteKit のバグと見なすべきか、Swift のバグと見なすべきかを判断するのは困難ですが、それは Apple の問題であって、あなたの問題ではありません。:)

コードをプレイグラウンドに貼り付ければ、問題は明らかです。コード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、どのサブクラスであるかを知らずに、特定のジョイント サブクラスに到達する必要があります。(繰り返しますが、これはバグを報告する良い機会です。)


physicsWorld(内部クラスのプレイグラウンドへの貼り付けから気付くかもしれませんPKPhysicsWorld:ただし、配列physicsWorldを扱うときはjoints、Swift 側で型キャストを行う必要があり、Swift は型チェックに関してはるかに厳密です。)

于 2015-02-13T18:08:52.083 に答える