Как использовать "enumerateChildNodesWithName" с Swift в SpriteKit?

Я использую Swift для создания игры в SpriteKit.

В Objective-C я мог бы использовать следующий метод:

 (void)enumerateChildNodesWithName:(NSString *)name usingBlock:(void (^)(SKNode *node, BOOL *stop))block

для выполнения действий над этим *node, но я не могу заставить эту функцию работать в Swift. В принципе, я не знаю, как ссылаться на node в Swift.

Это код, который я использую, но у меня возникают проблемы с частью "usingBlock:". Я пробовал много вещей много часов, но не удалось. Помоги пожалуйста!

func spawnEnemy() -> () {
  let enemy = SKSpriteNode(imageNamed: "enemy")
  enemy.name = "enemy"
  enemy.position = CGPointMake(100, 100)
  self.addChild(enemy)
}

func checkCollisions() -> () {
  self.enumerateChildNodesWithName("enemy", usingBlock: ((SKNode!, CMutablePointer<ObjCBool>) -> Void)?)
}

Ответы

Ответ 1

Пока не доверяйте автозаполнению, чтобы вставить нужный вам код - он падает в подписях из "заголовка", но сигнатура блока не совпадает с объявлением, которое вам нужно, когда вы вставляете свое собственное закрытие для параметра блока.

Формальным способом записи замыкания будет репликация подписи внутри фигурных скобок, добавление локальных имен параметров и использование ключевого слова in для отметки начала тела закрытия:

self.enumerateChildNodesWithName("enemy", usingBlock: {
    (node: SKNode!, stop: UnsafeMutablePointer <ObjCBool>) -> Void in 
    // do something with node or stop
})

Но вывод типа Swift означает, что вам не нужно так много писать. Вместо этого вы можете просто назвать параметры, потому что их тип (а также тип возврата закрытия) известен:

self.enumerateChildNodesWithName("enemy", usingBlock: {
    node, stop in 
    // do something with node or stop
})

Вы также можете использовать синтаксис закрывающего закрытия:

self.enumerateChildNodesWithName("enemy") {
    node, stop in 
    // do something with node or stop
}

(Вы даже можете отказаться от локальных имен параметров и ссылаться на параметры по положению - например, $0 для node - но здесь нет отличного места для этого, потому что это делает ваш код намного менее удобочитаемым. зарезервировать $0 и друзей для закрытий, где это ослепительно очевидно, какие параметры есть, например, закрытия, которые вы используете с map и sort.)

Подробнее см. Closures на языке Swift для программирования.


Кроме того, поскольку stop является UnsafeMutablePointer, синтаксис его использования немного отличается от того, что в ObjC: установите stop.memory = true, чтобы выйти из перечисления.