ios – 如何正确地将选择器作为参数传递给swift

前端之家收集整理的这篇文章主要介绍了ios – 如何正确地将选择器作为参数传递给swift前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
最后说

我有一个包含B的实例的A类.在A类中,我将一个A作为选择器的函数传递给B的一个方法.B使用这个选择器注册通知.但是,当通知进入时,它无法运行选择器并显示“无法识别的选择器发送到实例”.如果我把所有我想在B班做的事情都移到A班,那就行了.不过,我希望他们分开,好像更有条理.我对Objective-C和Swift来说相当新鲜,所以在这种情况下,我不知道如何传递选择器作为参数.斯威夫特答案会很棒.

ViewController.swift

  1. class ViewController: UIViewController {
  2.  
  3. var sessionCtrl : GKSessionControllerH!
  4.  
  5. override func viewDidLoad() {
  6. super.viewDidLoad()
  7. // Do any additional setup after loading the view,typically from a nib.
  8.  
  9. sessionCtrl = GKSessionControllerH()
  10.  
  11. // register notifications
  12. registerNotification()
  13. }
  14.  
  15. func registerNotification() {
  16. sessionCtrl.registerNotification(GKGesture.Up,gestureHandler: "gestureUpHandler")
  17. }
  18.  
  19. func gestureUpHandler() {
  20. dispatch_async(dispatch_get_main_queue()) {
  21. self.slidesViewCtrl!.prevPage()
  22. }
  23. }
  24. }

GKSessionControllerH.swift

  1. class GKSessionControllerH: NSObject,WCSessionDelegate {
  2.  
  3. func handleGestureContent(content : AnyObject?) {
  4.  
  5. // retrieve gesture
  6. let gesture = GKGesture(rawValue: content as! String)!
  7. print("Handheld device receives \(gesture)")
  8.  
  9. // post notification
  10. let notificationName = "ReceiveGesture\(gesture.rawValue)"
  11. NSNotificationCenter.defaultCenter().postNotificationName(notificationName,object: nil)
  12.  
  13. }
  14.  
  15. func registerNotification(gesture : GKGesture,gestureHandler : Selector) {
  16.  
  17. let notificationName = "ReceiveGesture\(gesture.rawValue)"
  18. NSNotificationCenter.defaultCenter().addObserver(self,selector: gestureHandler,name: notificationName,object: nil)
  19.  
  20. }
  21. }

调试信息

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

解决方法

以下是您的控制台输出中的大线索:

-[Slider.GKSessionControllerH gestureDownHandler]: unrecognized selector sent to instance 0x7f912857a420

所以,问题是,而不是试图在您的ViewController上调用gestureDownHandler,GKSessionControllerH正在注册通知的接收者.

我们需要传递选择器和对象来调用选择器.

  1. func registerNotification(gesture: GKGesture,gestureHandler: AnyObject,selector: Selector) {
  2. let notificationName = "ReceiveGesture\(gesture.rawValue)"
  3. NSNotificationCenter.defaultCenter().addObserver(gestureHandler,object: nil)
  4. }

而现在,要注册

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

或者,可以说更像Swift,我们可以采取更多的封闭式方法.

首先,让我们让GKSessionControllerH收到通知,我们会传递一个闭包,当收到通知时,它将跟踪调用.

在GKSessionControllerH中,

  1. var gestureActions = [()->Void] // an array of void-void closures
  2.  
  3. func gestureHandler() {
  4. for action in gestureActions {
  5. action()
  6. }
  7. }
  8.  
  9. func registerNotification(gesture: GKGesture,action:()->Void) {
  10. let notificationName = "ReceiveGesture\(gesture.rawValue)"
  11. NSNotificationCenter.defaultCenter().addObserver(self,selector: "gestureHandler",object: nil)
  12. }

现在,我们通过一个闭包(可以是一个方法):

在ViewController中:

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

现在显然,这将需要更多的逻辑来处理所有不同的手势类型,但它的要点在这里.

猜你在找的iOS相关文章