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类别中使用相同的方法,则会发生同样的崩溃。