ios - How to correctly pass selector as parameter in swift -
conclusively speaking
i have class contains instances of b. , in class a, pass function of selector method of b. , b use selector register notification. however, when notification comes in, not run selector , show "unrecognized selector sent instance". if move want in class b class a, worked. however, want them separated seems more organized. new objective-c , swift, therefore, don't know how pass selector parameter in case. answer in swift great.
viewcontroller.swift
class viewcontroller: uiviewcontroller { var sessionctrl : gksessioncontrollerh! override func viewdidload() { super.viewdidload() // additional setup after loading view, typically 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) } } debug info
2015-07-08 17:26:26.534 slider[4608:1719498] -[slider.gksessioncontrollerh gesturedownhandler]: unrecognized selector sent instance 0x7f912857a420 2015-07-08 17:26:26.543 slider[4608:1719498] *** terminating app due uncaught exception 'nsinvalidargumentexception', reason: '-[slider.gksessioncontrollerh gesturedownhandler]: unrecognized selector sent 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 uncaught exception of type nsexception
here's big clue in console output:
-[slider.gksessioncontrollerh gesturedownhandler]: unrecognized selector sent instance 0x7f912857a420
so, problem rather attempting call gesturedownhandler on viewcontroller, gksessioncontrollerh registering receiver of notification.
we need pass in both selector and object call selector on.
func registernotification(gesture: gkgesture, gesturehandler: anyobject, selector: selector) { let notificationname = "receivegesture\(gesture.rawvalue)" nsnotificationcenter.defaultcenter().addobserver(gesturehandler, selector: gesturehandler, name: notificationname, object: nil) } and now, register:
sessionctrl.registernotification(.up, gesturehandler: self, selector: "gestureuphandler") alternatively, , arguably more swift-like, can take more closure-based approach.
first, let's make gksessioncontrollerh receive notifications, , we'll pass closure, it'll keep track of call when notification received.
in gksessioncontrollerh,
var gestureactions = [()->void] // array of void-void closures func gesturehandler() { 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) } and now, pass in closure (which can method):
in viewcontroller:
func registernotification() { sessionctrl.registernotification(.up, action: gestureuphandler) } now obviously, need little more logic handle different gesture types, gist of here.
Comments
Post a Comment