为什么没有调用单独类上的SKPhysicsContactDelegate

时间:2017-01-31 15:29:31

标签: swift sprite-kit

我一直在尝试将联系代表添加到我的GameScene:

self.physicsWorld.contactDelegate = ContactManager()

但是,我这样做是通过将联系委托(ContactManager类)放在一个单独的类上来避免在我的GameScene上有那么多代码。这是我的联系代表:

class ContactManager : NSObject, SKPhysicsContactDelegate {

   func didBegin(_ contact: SKPhysicsContact) {
      print("they touched!")
   }

}

问题是当对象1与对象2发生碰撞时,它不会运行方法didBegin()。但是,我知道问题不在于bitmasks,因为我让GameScene继承了SKPhysicsContactDelete并将委托设置为self并且方法didBegin()工作。所以问题是类ContactManager()没有正确链接,我如何确保与GameScene不同的类上的联系人管理器工作?

2 个答案:

答案 0 :(得分:2)

SKPhysicsWorld上的

contactDelegateunowned(unsafe),这意味着它不会增加保留计数器,也不会被视为可选项。

这意味着您有责任保留放入此变量的任何对象。

在您的代码self.physicsWorld.contactDelegate = ContactManager()中您将联系人委托设置为ContactManager的本地副本。由于没有保留这一点,因此将立即丢弃它,因为保留计数设置为0。

这就是为什么在大多数情况下,人们使用self作为代理,因为您可以保证self存在。

要解决此问题,请确保您拥有保留ContactManger的属性,以便在创建时不会丢失它。

class Example : SKScene
{
  let contactManager = ContactManager()
  func someKindOfSetup()
  { 
    self.physicsWorld.contactDelegate = contactManager
  }
}

来源: https://developer.apple.com/reference/spritekit/skphysicsworld/1449602-contactdelegate

答案 1 :(得分:1)

根据旋风:

  

只能将一个对象设置为物理世界的委托。因此,如果您设置self.physicsWorld.contactDelegate = contactManagerInstance,稍后在代码中再次将其设置为self(其中self是场景),则只有场景才会收到联系人通知。因此,您可以让一个场景监听联系人或ContactManager。所以基本上做Knight0fDragon所说的,制作一个属性并将其设置为联系代表。