2017-12-12 9 views
1

All documentationand examples sagen, dass, wenn eine CFSocketCallBack callout der Buchse ist ein .dataCallback als zweiter Parameter (callbackType) gegeben, das kann die vierten (data) zu einem CFData Objekt geworfen werden, die alle Daten aus der Steckdose vorgelesen impliziert, dass.Wie handhabe ich CFSocketCallBackType.dataCallback in Swift?

Allerdings, wenn ich versuche, dies zu tun, ist es nicht:

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> 
} 

Der Absturz ich erhalte, ist dies:

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

Im Debugger, wenn ich diesen Typ:

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

es druckt nur eine Zeigeradresse (ziemlich hoch, auch; nur zwei signifikante 0 s). Allerdings, wenn ich das hier schreibe:

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

Er druckt diese:

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

So scheint es, was ich habe ist nicht wirklich ein CFData, aber es ist nah genug, um ähnlich auf der Oberfläche, um es zu scheinen, bis etwas tatsächlich versucht, es als solches zu lesen.

Also, was passiert hier, wo sind meine Daten und wie behebe ich das?

Antwort

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

liest einen CFData Zeiger von der Speicherstelle, dass callBackTypeMetaData! Punkte auf. Was Sie wollen, ist es, „neu zu interpretieren“ den Rohzeiger als CFData (oder NSData) Zeiger:

+0

, die definitiv den Absturz beseitigt! Aber ich verstehe nicht ganz, warum ... Ich dachte, dass "Speicher an der Adresse eines Zeigers als ein Typ behandeln" dasselbe war wie "einen Rohzeiger als einen Typ neu interpretieren". Wie unterscheiden sich diese beiden Ansätze und wie kann ich diesen Unterschied in der Zukunft erkennen? –

+0

Auch, wenn ich "Daten" im Debugger ausgibt, heißt es, die Bytezahl ist "0" und der Zeiger ist "0x000000000000bad0" bei jedem Lauf –

+0

@BenLeggiero: Ihr Code lädt "Daten" aus dem Speicher, dass ' callBackTypeMetaData! 'zeigt auf. Mein Code weist dem Wert von 'callBackTypeMetaData!' 'Data' zu, der Rest ist Typcasting für den Compiler. Die Dokumentation besagt, dass der rohe Zeiger "ein CFData-Objekt ist, nicht dass er auf ein CFData-Objekt zeigt". –

Verwandte Themen