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