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调用此方法。

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

我有时会得到这个错误消息(比如5中的1)会导致应用程序崩溃:

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

我抬头看PKPhysicsContact ,它是一个私人框架( 链接 )的一部分。 SKPhysicsContact看起来像只是一个空的类定义,只暴露了PKPhysicsContact某些属性。

我觉得这是SpriteKit团队的Objective-C攻击,打破了Swift强大的打字能力。

帮帮我?

如何确保我总是得到SKPhysicsContact回来?


我添加了一个检查来testingSKPhysicsContact

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

正确地捕捉types不匹配。

事实上,它从来没有返回一个SKPhysicsContact !!?


我已经尝试过在Objective-C中做这个(按照响应者的build议),我得到了相同的结果。

我有一个关于苹果开发者论坛的讨论 ,可能会提供未来的答案,寻求一些帮助。

下面是Objective-C的代码供参考:

 @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' 

为苹果添加了错误报告,#23332190

我得到这个简单的代码相同的错误:

 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) 

问题是, contact的types是PKPhysicsContact (正如你所注意到的),即使你明确地告诉它是一个SKPhysicsContact ,并且扩展名在SKPhysicsContact 。 你必须能够扩展到PKPhysicsContact这个工作。 从这个逻辑,我们可以说现在没有实例方法在SKPhysicsContact扩展中工作。 我会说这是一个SpriteKit的bug,你应该提交一个雷达 。 类方法仍然工作,因为你在类本身调用它们。

同时,您应该能够将该方法移动到您的场景或其他对象中,并成功调用它。


logging,这不是一个Swift的具体问题。 如果您在SKPhysicsContact的Objective-C类别中使用相同的方法,则会发生同样的崩溃。