didBeginContact传递了PKPhyicsObject [英] didBeginContact passed PKPhyicsObject

查看:72
本文介绍了didBeginContact传递了PKPhyicsObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个扩展SKPhysicsContact

extension SKPhysicsContact {

    /// - returns: `[SKPhysicsBody]` containing all the bodies that match `mask`
    func bodiesMatchingCategory(mask: UInt32) -> [SKPhysicsBody] {
        let bodies = [bodyA, bodyB]
        return bodies.filter { ($0.categoryBitMask & mask) != 0 }
    }
}

didBeginContact()中的

我在传入的contact中调用此方法.

in didBeginContact() I call this method on the passed in contact.

func didBeginContact(contact: SKPhysicsContact) {
    let ballMask: UInt32 = 0x1 << 2
    let ball = contact.bodiesMatchingCategory(ballMask)
...

有时我会收到此错误消息(如5分之一),导致应用程序崩溃:

I get this error message sometimes (like 1 in 5) which crashes the app:

-[PKPhysicsContact bodiesMatchingCategory:]: unrecognized selector sent to instance 0x165f2350

我查找了PKPhysicsContact,它是私有框架的一部分(

I looked up PKPhysicsContact and it's part of a private framework (link). SKPhysicsContact looks like it's just an empty class definition which exposes only certain properties of PKPhysicsContact.

我觉得这是SpriteKit团队的Objective-C破解,破坏了Swift的强大输入功能.

I feel like this is an Objective-C hack on the SpriteKit team that breaks Swift's strong typing.

帮助?

如何确保我总是回来SKPhysicsContact?

我添加了一张支票以测试SKPhysicsContact

I added a check to test for SKPhysicsContact

let test = contact as Any
print("Test is: \(test)")
guard test is SKPhysicsContact else {
    return
}

正确捕获类型不匹配的地方.

Which correctly catches the type mis-match.

实际上,它从不返回SKPhysicsContact !!!

In fact, it NEVER returns a SKPhysicsContact!!?

我已尝试在Objective-C中执行此操作(如响应者所建议),并且得到的结果相同.

I've tried doing this in Objective-C (as suggested by responder) and I'm getting the same result.

我在 Apple Dev论坛上进行了讨论,这可能会为将来的求职者提供帮助一些帮助.

I have a discussion on the Apple Dev Forums which may provide future answer-seekers some help.

这是供参考的Objective-C代码:

Here's the Objective-C code for reference:

@interface SKPhysicsContact (MatchingBodies)

- (NSArray *)bodiesMatchingCategory:(UInt32)category;

@end

@implementation SKPhysicsContact (MatchingBodies)

- (NSArray *)bodiesMatchingCategory:(UInt32)category {
    NSArray *bodies = @[self.bodyA, self.bodyB];

    NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(SKPhysicsBody *body, NSDictionary *bindings) {
        return (body.categoryBitMask & category) != 0;
    }];
    NSArray *matching = [bodies filteredArrayUsingPredicate:predicate];
    return matching;
}

@end

在这里打电话:

-(void)didBeginContact:(SKPhysicsContact *)contact
{
    static const uint32_t MarbleContact = 0x1 <<1;  // 2
    static const uint32_t GoalContact = 0x1 <<2;    // 4

    SKPhysicsBody *ball = [contact bodiesMatchingCategory:MarbleContact].firstObject;
    NSLog(@"Ball: %@", ball);
    ...

返回此崩溃:

-[PKPhysicsContact bodiesMatchingCategory:]: unrecognized selector sent to instance 0x17dad9e0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PKPhysicsContact bodiesMatchingCategory:]: unrecognized selector sent to instance 0x17dad9e0'


添加了针对Apple的错误报告#23332190


Added Bug Report for Apple, #23332190

推荐答案

我用以下简单代码得到了相同的错误:

I get the same error with this simple code:

extension SKPhysicsContact {
    func bodiesMatchingCategory(mask: UInt32) -> [SKPhysicsBody] {
        let bodies = [bodyA, bodyB]
        return bodies.filter { ($0.categoryBitMask & mask) != 0 }
    }
}

let contact = SKPhysicsContact()
let body = contact.bodiesMatchingCategory(0)

问题是,即使您显式地将其指定为SKPhysicsContact并且扩展名位于SKPhysicsContact上,contact的类型也为PKPhysicsContact(如您所注意到的).您必须能够扩展PKPhysicsContact才能起作用.根据这种逻辑,我们可以说目前没有实例方法在SKPhysicsContact扩展中将起作用.我会说这是SpriteKit的一个错误,您应该提交雷达.自从您在类本身上调用类方法以来,类方法仍然有效.

The problem is, the type of contact is PKPhysicsContact (as you've noticed), even when you explicitly tell it to be an SKPhysicsContact, and the extension is on SKPhysicsContact. You'd have to be able to make an extension to PKPhysicsContact for this to work. From this logic, we can say that no instance methods will work in SKPhysicsContact extensions at the moment. I'd say it's a bug with SpriteKit, and you should file a radar. Class methods still work since you call them on the class itself.

同时,您应该能够将该方法移至场景或其他对象中并在其中成功调用.

In the meantime, you should be able to move that method into your scene or another object and call it there successfully.

记录下来,这不是Swift特有的问题.如果您在SKPhysicsContact上的Objective-C类别中使用相同的方法,则会遇到相同的崩溃.

For the record, this is not a Swift-specific problem. If you make the same method in an Objective-C category on SKPhysicsContact you'll get the same crash.

这篇关于didBeginContact传递了PKPhyicsObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆