2

所有文档 和示例都说,如果给套接字的CFSocketCallBack标注 a.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的 s)。但是,当我输入以下内容时:

(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.

所以看起来我得到的并不是真正的 a CFData,但它足够接近,表面上看起来和它很相似,直到有东西真的试图这样解读它。

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

4

1 回答 1

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

CFData从指向的内存位置读取一个指针callBackTypeMetaData!。您想要的是将原始指针“重新解释”为CFData(或NSData)指针:

if callBackType == .dataCallBack {
    if let rawPointer = callBackTypeMetaData  {
        let data = Unmanaged<NSData>.fromOpaque(rawPointer).takeUnretainedValue() as Data
        // ...
    }
}
于 2017-12-12T19:48:54.927 回答