我正在做一个SpriteKit项目。我通过node.physicsBody?.joints访问节点的关节。

它应该包含一个SKPhysicsJointPin,实际上我正在得到一个包含一个SKPhysicsJoint对象的数组。

但我无法将其从SKPhysicsJoint转换为SKPhysicsJointPin

for joint in (node.physicsBody?.joints)! {
    print("Joint found") // Is executed
    if let myJoint = joint as? SKPhysicsJointPin {
      print("SKPhysicsJointPin object found") // Is not executed
    }
}


我创建的关节当然是SKPhysicsJointPin对象,但是我的程序不执行第二条打印语句。

为什么无法向下转换呢?我偶然发现了一个错误吗?

谢谢

最佳答案

是的+[SKPhysicsJointPin allocWithZone:]返回PKPhysicsJointRevolute

             +[SKPhysicsJointPin allocWithZone:]:
000b8bd4         push       ebp                                                 ; Objective C Implementation defined at 0x1817fc (class)
000b8bd5         mov        ebp, esp
000b8bd7         sub        esp, 0x18
000b8bda         call       0xb8bdf
000b8bdf         pop        eax                                                 ; XREF=+[SKPhysicsJointPin allocWithZone:]+6
000b8be0         mov        ecx, dword [ss:ebp+arg_8]
000b8be3         mov        edx, dword [ds:eax-0xb8bdf+objc_cls_ref_PKPhysicsJointRevolute] ; objc_cls_ref_PKPhysicsJointRevolute
000b8be9         mov        eax, dword [ds:eax-0xb8bdf+0x16e5b0]                ; @selector(allocWithZone:)
000b8bef         mov        dword [ss:esp+0x18+var_10], ecx
000b8bf3         mov        dword [ss:esp+0x18+var_14], eax                     ; argument "selector" for method imp___symbol_stub__objc_msgSend
000b8bf7         mov        dword [ss:esp+0x18+var_18], edx                     ; argument "instance" for method imp___symbol_stub__objc_msgSend
000b8bfa         call       imp___symbol_stub__objc_msgSend
000b8bff         add        esp, 0x18
000b8c02         pop        ebp
000b8c03         ret
                        ; endp


这是PhysicsKit(私有框架)中的类。在ObjC中,这无关紧要,因为类型就是我们所说的类型,只要对象响应正确的选择器即可。在Swift中,这会导致类型不匹配,因为类型不只是我们所说的那样。

您可能会在ObjC中创建一个桥梁以使其正常工作,但是您可能会遇到“使用私有框架”的问题。桥看起来像这样(未经测试):

// Trust me, compiler, this class will exist at runtime
@class PKPhysicsJoinRevolute;

// And hey, here are some methods that I also promise will exist.
@interface PKPhysicsJointRevolute (Bridge)
@property(nonatomic) CGFloat rotationSpeed;
// ...  whatever properties you need ...
@end


但是就像我说的那样,这可能会给您带来麻烦。因此,相反,您可能想要制作一个(未测试的)ObjC包装器

@interface MYPinWrapper : NSObject
@property (nonatomic, readonly, strong) SKPhysicsJointPin *pin;
- (instancetype)initWithPin:(id)pin;
@end

@implementation MYPinWrapper {
- (instancetype)initWithPin:(id)pin {
    _pin = (SKPhysicsJointPin *)pin;
}
@end


然后,您的Swift看起来像:

for joint in (node.physicsBody?.joints)! {
    print("Joint found") // Is executed
    let pin = MYPinWrapper(pin: joint).pin // Launder the pin through ObjC
    // ... pin should now work like a pin even though it's really a revolute.
}

关于ios - 无法从SKPhysicsJoint转换为SKPhysicsJointPin(SpriteKit),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36841221/

10-12 06:02