Ios 如何在swift中正确地将选择器作为参数传递

Ios 如何在swift中正确地将选择器作为参数传递,ios,swift,selector,Ios,Swift,Selector,总而言之 我有一个包含B实例的类A。在类A中,我将A的函数作为选择器传递给B的方法。B使用此选择器注册通知。但是,当通知传入时,它无法运行选择器并显示“未识别的选择器已发送到实例”。如果我把我想在B班做的事情都转移到A班,它就成功了。但是,我希望他们分开,这样看起来更有条理。我对Objective-C和Swift相当陌生,因此,在这种情况下,我不知道如何将选择器作为参数传递。用Swift回答就好了 ViewController.swift class ViewController: UIView

总而言之

我有一个包含B实例的类A。在类A中,我将A的函数作为选择器传递给B的方法。B使用此选择器注册通知。但是,当通知传入时,它无法运行选择器并显示“未识别的选择器已发送到实例”。如果我把我想在B班做的事情都转移到A班,它就成功了。但是,我希望他们分开,这样看起来更有条理。我对Objective-C和Swift相当陌生,因此,在这种情况下,我不知道如何将选择器作为参数传递。用Swift回答就好了

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()
        }
    }
}
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)

    }
}
GKSessionControllerH.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()
        }
    }
}
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)

    }
}
调试信息

2015-07-08 17:26:26.534滑块[4608:1719498]-[Slider.GKSessionControllerH gestureDownHandler]:发送到实例0x7f912857a420的无法识别的选择器
2015-07-08 17:26:26.543 Slider[4608:1719498]***由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[Slider.GKSessionControllerH gestureDownHandler]:未识别的选择器发送到实例0x7f912857a420'
***第一次抛出调用堆栈:
(
0 CoreFoundation 0x000000010430dca5例外预处理+165
1 libobjc.A.dylib 0x00000001060f1dcd objc_异常_抛出+48
2 CoreFoundation 0x0000000104315fcd-[NSObject(NSObject)不识别选择器:][205
3 CoreFoundation 0x00000001042634ea\uuuuuuuuuuuuuuu+970
4 CoreFoundation 0x0000000104263098\u CF\u转发\u准备\u 0+120
5 CoreFoundation 0x00000001042db09c通知中心正在召集观察员
6 CoreFoundation 0x00000001042daddb\u CFXRegistrationPost+427
7 CoreFoundation 0x00000001042dab42\uuuuuuuuuuuxNotificationPost\u block\u invoke+50
8 CoreFoundation 0x000000010431d432-[\u cfxNotificationRegistrator查找:对象:观察者:枚举器:][1618
9核心基金会0x00000001041d3538\u CFXNotificationPost+632
10基金会0x000 000 01048 BB3C4 - [ NSnPosiCICTeCsPoestPosiTrimeTrimeNo:对象:用户信息:] + 66
11滑块0x00000001040f4e0e\u TFC6滑块20GK会话控制器H20句柄测试内容FS0\u FGSqPSs9AnyObject\u\u T\u+1086
12滑块0x00000001040f4689 \u TFC6滑块20GK会话控制器H7会话FS0 \u FTCSO9WCSession17未收到消息GVSS10字典SPSS9AnyObject \uuuuuuuuuuuuu+825
13滑块0x00000001040f49b7\u TTOFC6滑块20GK会话控制器H7会话FS0\u FTCSO9WCSession17未收到消息GVSS10字典SPSS9任何对象
14 WatchConnectivity 0x00000001060c18cd WatchConnectivity+35021
15 libdispatch.dylib 0x0000000106ab2b11调度调用块和释放+12
16 libdispatch.dylib 0x0000000106ad280d_dispatch_client_callout+8
17 libdispatch.dylib 0x0000000106ab92ec调度队列排水+2200
18 libdispatch.dylib 0x0000000106ab88ed_调度_队列_调用+233
19 libdispatch.dylib 0x0000000106abae9b_调度_根队列_排水+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:以NSException类型的未捕获异常终止

以下是控制台输出中的重要线索:

-[Slider.GKSessionControllerH gestureDownHandler]:发送到实例0x7f912857a420的选择器无法识别

因此,问题在于,
GKSessionControllerH
不是试图在
ViewController
上调用
gestureDownHandler
,而是将自己注册为通知的接收者

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

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

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

或者,我们可以采取一种更为基于闭包的方法,这种方法可以说更为迅速

首先,让我们让
GKSessionControllerH
接收通知,并向其传递一个闭包,它将跟踪在接收到通知时调用的闭包

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)
}
现在,我们传入一个闭包(可以是一个方法):

视图控制器中

func registerNotification() {
    sessionCtrl.registerNotification(.Up, action: gestureUpHandler)
}
显然,这需要更多的逻辑来处理所有不同的手势类型,但要点就在这里