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
,但它在表面上看起来很接近它,直到某些东西真的试图读它为止。
那么这里发生了什么,我的数据在哪里,我该如何解决?
答案 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
// ...
}
}