加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 如何使用实例方法作为只需func或文字关闭的函数的回调

发布时间:2020-12-14 05:36:52 所属栏目:百科 来源:网络整理
导读:在“ViewController. swift”中,我创建了这个回调: func callback(cf:CFNotificationCenter!,ump:UnsafeMutablePointerVoid,cfs:CFString!,up:UnsafePointerVoid,cfd:CFDictionary!) - Void {} 使用这个观察者: CFNotificationCenterAddObserver(CFNotific
在“ViewController. swift”中,我创建了这个回调:
func callback(cf:CFNotificationCenter!,ump:UnsafeMutablePointer<Void>,cfs:CFString!,up:UnsafePointer<Void>,cfd:CFDictionary!) -> Void {

}

使用这个观察者:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),nil,self.callback,"myMESSage",CFNotificationSuspensionBehavior.DeliverImmediately)

导致此编译器出现错误:
“C函数指针只能通过引用”func“或者是文字闭包来形成”

回调是指向C函数的指针,在Swift中可以通过
只有一个全局函数或闭包(不捕获任何状态),
但不是一个实例方法.

所以这样做是有效的:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),{ (_,observer,name,_,_) in
            print("received notification: (name)")
        },"myMessage",.DeliverImmediately)

但是由于闭包无法捕获上下文,因此您没有直接引用自身及其属性和实例方法.
例如,您不能添加

self.label.stringValue = "got it"
           // error: a C function pointer cannot be formed from a closure that captures context

在通知到达时,关闭内部更新UI.

有一个解决方案,但它有点复杂
Swift的严格型系统.
类似于Swift 2 – UnsafeMutablePointer<Void> to object,您可以将指针转换为
self到void指针,将其作为观察器参数传递
到注册,并将其转换回到一个对象指针
回调.

class YourClass { 

    func callback(name : String) {
        print("received notification: (name)")
    }

    func registerObserver() {

        // Void pointer to `self`:
        let observer = UnsafePointer<Void>(Unmanaged.passUnretained(self).toOpaque())

        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),_) -> Void in

                // Extract pointer to `self` from void pointer:
                let mySelf = Unmanaged<YourClass>.fromOpaque(
                        COpaquePointer(observer)).takeUnretainedValue()
                // Call instance method:
                mySelf.callback(name as String)
            },.DeliverImmediately)
    }

    // ...
}

封闭作为实例方法的“蹦床”.

指针是一个无法引用的参考,因此您必须确保
在对象被释放之前观察者被移除.

Swift 3的更新:

class YourClass {

    func callback(_ name : String) {
        print("received notification: (name)")
    }

    func registerObserver() {

        // Void pointer to `self`:
        let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque())

        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),_) -> Void in
                if let observer = observer,let name = name {

                    // Extract pointer to `self` from void pointer:
                    let mySelf = Unmanaged<YourClass>.fromOpaque(observer).takeUnretainedValue()
                    // Call instance method:
                    mySelf.callback(name.rawValue as String)
                }
            },"myMessage" as CFString,.deliverImmediately)
    }

    // ...
}

参见How to cast self to UnsafeMutablePointer<Void> type in swift了解更多信息关于对象指针和C指针之间的“桥接”.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读