ios swift selector

ios - Cómo pasar correctamente el selector como parámetro en swift



(1)

Aquí está la gran pista en la salida de su consola:

- [Slider.GKSessionControllerH gestionDownHandler]: selector no reconocido enviado a la instancia 0x7f912857a420

Entonces, el problema es que en lugar de intentar llamar a gestureDownHandler en su ViewController , GKSessionControllerH está registrando para ser el receptor de la notificación.

Necesitamos pasar tanto el selector como el objeto para activar el selector.

func registerNotification(gesture: GKGesture, gestureHandler: AnyObject, selector: Selector) { let notificationName = "ReceiveGesture/(gesture.rawValue)" NSNotificationCenter.defaultCenter().addObserver(gestureHandler, selector: gestureHandler, name: notificationName, object: nil) }

Y ahora, para registrarte:

sessionCtrl.registerNotification(.Up, gestureHandler: self, selector: "gestureUpHandler")

Alternativamente, y posiblemente más Swift-like, podemos adoptar un enfoque más basado en el cierre.

Primero, hagamos que GKSessionControllerH reciba las notificaciones, y le pasaremos un cierre, que mantendrá un registro de las llamadas cuando se reciba la notificación.

En GKSessionControllerH ,

var gestureActions = [()->Void] // an array of void-void closures func gestureHandler() { for action in gestureActions { action() } } func registerNotification(gesture: GKGesture, action:()->Void) { let notificationName = "ReceiveGesture/(gesture.rawValue)" NSNotificationCenter.defaultCenter().addObserver(self, selector: "gestureHandler", name: notificationName, object: nil) }

Y ahora, pasamos en un cierre (que puede ser un método):

En ViewController :

func registerNotification() { sessionCtrl.registerNotification(.Up, action: gestureUpHandler) }

Ahora, obviamente, esto necesitará un poco más de lógica para manejar todos sus diferentes tipos de gestos, pero la esencia de esto está aquí.

En conclusión, hablando

Tengo clase A que contiene instancias de B. Y en la clase A, paso una función de A como selector a un método de B. Y B usa este selector para registrar notificaciones. Sin embargo, cuando llega la notificación, no se pudo ejecutar el selector y mostrar "el selector no reconocido enviado a la instancia". Si muevo todo lo que quiero hacer en la clase B a la clase A, funcionó. Sin embargo, los quiero separados para que parezca más organizado. Soy bastante nuevo en Objective-C y Swift, por lo tanto, no sé cómo pasar el selector como parámetro en este caso. La respuesta en Swift sería genial.

ViewController.swift

class ViewController: UIViewController { var sessionCtrl : GKSessionControllerH! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. sessionCtrl = GKSessionControllerH() // register notifications registerNotification() } func registerNotification() { sessionCtrl.registerNotification(GKGesture.Up, gestureHandler: "gestureUpHandler") } func gestureUpHandler() { dispatch_async(dispatch_get_main_queue()) { self.slidesViewCtrl!.prevPage() } } }

GKSessionControllerH.swift

class GKSessionControllerH: NSObject, WCSessionDelegate { func handleGestureContent(content : AnyObject?) { // retrieve gesture let gesture = GKGesture(rawValue: content as! String)! print("Handheld device receives /(gesture)") // post notification let notificationName = "ReceiveGesture/(gesture.rawValue)" NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil) } func registerNotification(gesture : GKGesture, gestureHandler : Selector) { let notificationName = "ReceiveGesture/(gesture.rawValue)" NSNotificationCenter.defaultCenter().addObserver(self, selector: gestureHandler, name: notificationName, object: nil) } }

información de depuración

2015-07-08 17:26:26.534 Slider[4608:1719498] -[Slider.GKSessionControllerH gestureDownHandler]: unrecognized selector sent to instance 0x7f912857a420 2015-07-08 17:26:26.543 Slider[4608:1719498] *** Terminating app due to uncaught exception ''NSInvalidArgumentException'', reason: ''-[Slider.GKSessionControllerH gestureDownHandler]: unrecognized selector sent to instance 0x7f912857a420'' *** First throw call stack: ( 0 CoreFoundation 0x000000010430dca5 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001060f1dcd objc_exception_throw + 48 2 CoreFoundation 0x0000000104315fcd -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x00000001042634ea ___forwarding___ + 970 4 CoreFoundation 0x0000000104263098 _CF_forwarding_prep_0 + 120 5 CoreFoundation 0x00000001042db09c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12 6 CoreFoundation 0x00000001042daddb _CFXRegistrationPost + 427 7 CoreFoundation 0x00000001042dab42 ___CFXNotificationPost_block_invoke + 50 8 CoreFoundation 0x000000010431d432 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1618 9 CoreFoundation 0x00000001041d3538 _CFXNotificationPost + 632 10 Foundation 0x00000001048bb3c4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66 11 Slider 0x00000001040f4e0e _TFC6Slider20GKSessionControllerH20handleGestureContentfS0_FGSqPSs9AnyObject__T_ + 1086 12 Slider 0x00000001040f4689 _TFC6Slider20GKSessionControllerH7sessionfS0_FTCSo9WCSession17didReceiveMessageGVSs10DictionarySSPSs9AnyObject___T_ + 825 13 Slider 0x00000001040f49b7 _TToFC6Slider20GKSessionControllerH7sessionfS0_FTCSo9WCSession17didReceiveMessageGVSs10DictionarySSPSs9AnyObject___T_ + 119 14 WatchConnectivity 0x00000001060c18cd WatchConnectivity + 35021 15 libdispatch.dylib 0x0000000106ab2b11 _dispatch_call_block_and_release + 12 16 libdispatch.dylib 0x0000000106ad280d _dispatch_client_callout + 8 17 libdispatch.dylib 0x0000000106ab92ec _dispatch_queue_drain + 2200 18 libdispatch.dylib 0x0000000106ab88ed _dispatch_queue_invoke + 233 19 libdispatch.dylib 0x0000000106abae9b _dispatch_root_queue_drain + 1412 20 libdispatch.dylib 0x0000000106aba912 _dispatch_worker_thread3 + 111 21 libsystem_pthread.dylib 0x0000000106e11637 _pthread_wqthread + 729 22 libsystem_pthread.dylib 0x0000000106e0f40d start_wqthread + 13 ) libc++abi.dylib: terminating with uncaught exception of type NSException