第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用實例方法作為只接受func或文字閉包的函數(shù)的回調(diào)

如何使用實例方法作為只接受func或文字閉包的函數(shù)的回調(diào)

守著一只汪 2019-08-05 14:22:28
如何使用實例方法作為只接受func或文字閉包的函數(shù)的回調(diào)在“ViewController.swift”中我創(chuàng)建了這個回調(diào):func callback(cf:CFNotificationCenter!,      ump:UnsafeMutablePointer<Void>,      cfs:CFString!,      up:UnsafePointer<Void>,      cfd:CFDictionary!) -> Void {}使用此觀察者:CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),      nil,      self.callback,      "myMESSage",      nil,      CFNotificationSuspensionBehavior.DeliverImmediately)導(dǎo)致此編譯器錯誤:“AC函數(shù)指針只能通過對'func'或文字閉包的引用形成”
查看完整描述

2 回答

?
犯罪嫌疑人X

TA貢獻(xiàn)2080條經(jīng)驗 獲得超4個贊

回調(diào)是指向C函數(shù)的指針,在Swift中,您只能傳遞全局函數(shù)或閉包(不捕獲任何狀態(tài)),但不能傳遞實例方法。

所以這確實有效:

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

但由于閉包無法捕獲上下文,因此您無法直接引用self其屬性和實例方法。例如,您無法添加

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

在閉包內(nèi)部,在通知到達(dá)時更新UI。

有一個解決方案,但由于Swift嚴(yán)格的類型系統(tǒng),它有點復(fù)雜。與Swift 2 - UnsafeMutablePointer <Void>中的對象類似,您可以將指針轉(zhuǎn)換 self為void指針,將其作為observer參數(shù)傳遞給注冊,并將其轉(zhuǎn)換回回調(diào)中的對象指針。

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(),
            observer,
            { (_, observer, name, _, _) -> 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)
            },
            "myMessage",
            nil,
            .DeliverImmediately)
    }
    // ...}

閉包充當(dāng)實例方法的“蹦床”。

指針是未保留的引用,因此必須確保在取消分配對象之前刪除觀察者。


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(),
            observer,
            { (_, observer, name, _, _) -> 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,
            nil,
            .deliverImmediately)
    }
    // ...}

有關(guān)對象指針和C指針之間“橋接”的更多信息,另請參見如何將self轉(zhuǎn)換為UnsafeMutablePointer <Void>鍵入swift。


查看完整回答
反對 回復(fù) 2019-08-05
?
慕田峪4524236

TA貢獻(xiàn)1875條經(jīng)驗 獲得超5個贊

在我的例子中,我想從我的閉包中調(diào)用的函數(shù)是在AppDelegate中。所以我能夠使用委托從閉包中調(diào)用函數(shù)而不使用self。這是否是一個主意是具有更多經(jīng)驗的人必須評論的東西。

        self.pingSocket = CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_DGRAM, IPPROTO_ICMP,CFSocketCallBackType.dataCallBack.rawValue, {socket, type, address, data, info in
            //type is CFSocketCallBackType
            guard let socket = socket, let address = address, let data = data, let info = info else { return }// stuff deleted, including use of C pointers
            let appDelegate = NSApplication.shared.delegate as! AppDelegate
            appDelegate.receivedPing(ip: sourceIP, sequence: sequence, id: id)
            //}
            return
        }, &context)extension AppDelegate: ReceivedPingDelegate {
    func receivedPing(ip: UInt32, sequence: UInt16, id: UInt16) {
        // stuff deleted
    }}protocol ReceivedPingDelegate: class {
    func receivedPing(ip: UInt32, sequence: UInt16, id: UInt16)}


查看完整回答
反對 回復(fù) 2019-08-05
  • 2 回答
  • 0 關(guān)注
  • 498 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號