All documentation and examples假设一个套接字的 CFSocketCallBack
callout 被赋予一个 .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
,但它足够接近,看起来与表面上的相似,直到有东西真正尝试读取它。
那么这里发生了什么,我的数据在哪里,以及如何解决这个问题?
最佳答案
data = callBackTypeMetaData!.load(as: CFData.self)
从 callBackTypeMetaData!
指向的内存位置读取 CFData
指针。你想要的是“重新诠释”
原始指针作为 CFData
(或 NSData
)指针:
if callBackType == .dataCallBack {
if let rawPointer = callBackTypeMetaData {
let data = Unmanaged<NSData>.fromOpaque(rawPointer).takeUnretainedValue() as Data
// ...
}
}
关于swift - 如何在 Swift 中处理 CFSocketCallBackType.dataCallback?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47780246/