Как мне обработать CFSocketCallBackType.dataCallback в Swift?
Вся документация и примеры говорят, что если сокет 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 ответ
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
// ...
}
}