Таким образом, я делаю SpriteKit игру, и я хочу, чтобы направить update
, mouseDown
, keyDown
и т.д. ... события, которые вызываются на GameScene
, к тому, что сцены дети, при условии, что они являются обычным подклассом SKNode, у которого есть соответствующие респонденты.Общий механизм отправки с помощью выполнения заданных испытаний Протокол соответствия & селектор
Я сделал несколько протоколов в зависимости от того, какие функции я хочу вызвать на каждом узле, так как у меня есть KeyboardDelegate
для узлов, которые должны получить keyDown
, keyUp
и т.д ... UpdateDelegate
для update
, didSimulatePhysics
и т.д ... и что-то вроде этого для каждого типа вызовов в целом у меня есть UpdateDelegate
, KeyboardDelegate
, MouseDelegate
и CollisionDelegate
каждый для соответствующего типа вызовов.
И так в GameScene
у меня есть такие функции, как:
func someEvent(someParameter: ArgumentType) {
for child in children where child is SomeProtocol {
//onSomeEvent should be required by SomeProtocol
(child as! SomeProtocol).onSomeEvent(someParameter)
}
}
Проблема заключается в том, что существует около 20 таких событий, которые я хочу вперед и у меня есть тот же самый код в каждой функции, единственная часть которые варьируются: SomeProtocol
и onSomeEvent
.
Я попытался сделать функцию, которая обрабатывает все, что так мне не нужно писать этот код для каждого события, я хочу передать так:
extension SKNode {
func forward<T>(method: Selector, onChildrenOfType: T.Type, withArgument argument: AnyObject) {
for child in children where child is T {
child.performSelector(method, withObject: first)
}
}
}
Расширения было на SKNode, так что я бы способные переадресовывать вызовы на каждого ребенка каждого отдельного узла, принимающего вызов, независимо от того, какой тип SKNode они были.
Сама функция не казалась совершенно прав, и это не потому, что он не работает, я не мог пройти протокол напрямую, без использования SomeProtocol.self
и всякий раз, когда я назвал это так:
override func someEvent(someParameter: ArgumentType) {
self.recurse(#selector(onSomeEvent(_:)), onChildrenOfType: SomeProtocol.self, withArgument: someParameter)
}
Я бы получил use of unresolved identifier 'onSomeEvent'
, я предполагаю, потому что компилятор не знает, где искать функцию onSomeEvent
.
Итак ... есть ли способ, чтобы сделать эту работу (к тому же, возможно, используя старый синтаксис селекторов), предпочтительно, если я могу передать более, что 2 параметра (так как performSelector только позволяет до 2, и objc_msgSend
и NSInvocation
недоступны), или я должен просто придерживаться копирования кода в каждом событии, которое я хочу переслать.
Спасибо, поэтому решение, по-видимому, использовало SomeProtocol.onSomeEvent при создании селектора, теперь оно работает. Хотя вы только что вспомнили, что существует NSNotificationCenter, поэтому я посмотрю, может ли это быть более полезным. +1 за предложение использовать метод flatMap (хотя фильтра достаточно) – lsauceda
Вы правы, использование 'flatMap' было неэффективным. Изменен как полностью функциональный стиль, если методы что-то вычислили. – BaseZen
Хм, я больше думал о (array.filter {$ 0.conformsToProtocol (соответствовать)}). ForEach {$ 0.performSelector (action)} вместо обновленного кода, потому что мне не нужен фильтрованный массив после выполнения селекторы. – lsauceda