如何在Swift中处理CFSocketCallBackType.dataCallback?

时间:2017-12-12 19:35:12

标签: swift sockets unsafe-pointers cfsocket

All documentation and examples说如果套接字的CFSocketCallBack标注被赋予.dataCallback作为其第二个参数(callbackType),则表示可以将第四个(data)强制转换为包含从套接字预读的所有数据的CFData对象。

然而,当我尝试这样做时,它失败了:

private func myCallout(socket: CFSocket?,
                       callBackType: CFSocketCallBackType,
                       address: CFData?,
                       callBackTypeMetaData: UnsafeRawPointer?,
                       info: UnsafeMutableRawPointer?) -> Void {

    // Behavior inferred from Developer
    // https://developer.apple.com/documentation/corefoundation/cfsocketcallback

    guard
        let info = info,
        let socket = socket
        else {
        return assertionFailure("Socket may have gone out of scope before response")
    }

    // <REDACTED>


    if callBackType == .dataCallBack {
        guard let data = callBackTypeMetaData?.load(as: CFData.self) else {
            return assertionFailure("Data Callback's metadata was not a CFData object")
        }

        foo(data as Data) // Crashes here
    }

    // <REDACTED>
}

我得到的崩溃是这样的:

Thread 1: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0).

在调试器中,当我输入:

(lldb) po callBackTypeMetaData!.load(as: CFData.self)

它只是打印一个指针地址(相当高,同样;只有两个重要的0)。但是,当我输入此内容时:

(lldb) po callBackTypeMetaData!.load(as: CFData.self) as Data

打印出来:

error: Execution was interrupted, reason: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0).
The process has been returned to the state before expression evaluation.

所以看起来我得到的并不是真正的CFData,但它在表面上看起来很接近它,直到某些东西真的试图读它为止。

那么这里发生了什么,我的数据在哪里,我该如何解决?

1 个答案:

答案 0 :(得分:2)

data = callBackTypeMetaData!.load(as: CFData.self)

CFData指向的内存位置读取callBackTypeMetaData!指针。你想要的是&#34;重新解释&#34; 原始指针为CFData(或NSData)指针:

if callBackType == .dataCallBack {
    if let rawPointer = callBackTypeMetaData  {
        let data = Unmanaged<NSData>.fromOpaque(rawPointer).takeUnretainedValue() as Data
        // ...
    }
}