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


Я использую Swift, чтобы сделать игру в SpriteKit.

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

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

Для выполнения действий над этим *node, но я не могу заставить эту функцию работать в Swift. В принципе, я не знаю, как ссылаться на этот узел в 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 17

1 ответ:

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

Формальным способом записи замыкания было бы копирование подписи внутри фигурных скобок, добавление имен локальных параметров и использование ключевого слова in для обозначения начала тела замыкания:
self.enumerateChildNodesWithName("enemy", usingBlock: {
    (node: SKNode!, stop: UnsafeMutablePointer <ObjCBool>) -> Void in 
    // do something with node or stop
})

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

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.)

Смотритезамыкания вязыке программирования Swift для дальнейшего объяснения.


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