2014-09-26 4 views
8

In Objective-C, quando si NSLog un oggetto o po in lldb, l'oggetto riceve il messaggio description.Cosa succede quando si stampa un oggetto Swift (po) in lldb?

In Swift tuttavia, il comportamento sembra essere diverso. Ho implementato sia Printable (richiede la proprietà description) e DebugPrintable (che richiede a sua volta una proprietà denominata debugDescription). Se provo a println() un oggetto o po esso, nessuna di quelle proprietà viene chiamata.

Cosa sta succedendo? Quali sono quei protocolli per allora ??

risposta

6

(applicazioni compilate in simulatore o xcrun swiftc) C'è un problema noto che Printable viene ignorato dal Swift REPL (vale a dire, tutto ciò in un parco giochi o gestita da xcrun swift dalla riga di comando), ma riconosciuto dal compilatore.

Per esempio, ecco il codice di "foo.swift":

struct Person : Printable { 
    let name: String 

    var description: String { 
     return "\(name)" 
    } 
} 

let me = Person(name: "Nate") 
println(me) 

Se l'eseguo con il REPL, ottengo questo:

$ xcrun swift foo.swift 
foo.Person 

Ma se compilo in primo luogo, e quindi eseguirlo, si utilizza la proprietà description calcolata:

$ xcrun -sdk macosx swiftc foo.swift ; ./foo 
Nate 

Il protocollo DebugPrintable è utile se si desidera essere in grado di utilizzare le funzioni debugPrint e debugPrintln: in codice compilato, viene stampata la proprietà debugDescription di un'istanza.

+0

Chi avrebbe mai pensato ... Grazie! ;-) – cfischer

+0

BTW, se questa descrizione è vera, c'è qualche ragione per implementare DebugPrintable? – cfischer

+0

@cfisher Non ne ho idea! :) –

4

solo per aggiungere qualche dettaglio in più alla risposta di Nate:

  • in Xcode 6, quando si tenta di "po" un oggetto di Swift, una delle due cose accada:

    • l'oggetto è in realtà un oggetto Objective-C (ad esempio NSWindow, NSString) o un optional di tale tipo. In questo caso, LLDB scartoccia se necessario, quindi chiama NSPrintForDebugger (objcpointer). Ciò significa che gli oggetti ObjC devono "po" essere gli stessi in Swift come in Objective-C

    • l'oggetto è in realtà un oggetto Swift. In questo caso, LLDB utilizza i propri formattatori di dati per la stampa l'oggetto, con un paio di modifiche minori per dare un "po" sguardo -esque, ma non importa quali protocolli sono attrezzi oggetti, essi vengono ignorati

Come miglioramento futuro, l'idea è che LLDB sarà in grado di chiedere la libreria standard di Swift a DebugString (oggetto), e lasciare che la libreria Swift gestisca i dettagli di cosa significhi l'operazione - proprio come NSPrintForDebugger() nell'Objective-C mondo.

In questo universo avanzato, il contratto della Libreria standard potrebbe benissimo essere che l'implementazione di Stampabile, o DebugPrintable, influirebbe sul risultato di toDebugString(). LLDB si impegna automaticamente perché è solo delegando la responsabilità.

Anche in un universo così avanzato, il tuo chilometraggio in modalità REPL varierà a causa delle limitazioni del JIT. Per inciso, la stessa limitazione rende impossibile di definire un tipo in un parco giochi e personalizzare il modo in cui è presentato (che richiederebbe attuazione almeno uno dei protocolli Reflectable/specchio)

+0

Ma tutti gli oggetti * in Swift sono oggetti Objective-C - tutti gli oggetti possono essere utilizzati con il runtime Objective-C (non tutti i membri possono essere disponibili per Objective-C, ma l'oggetto stesso è altrettanto valido oggetto come qualsiasi altro oggetto) – newacct

+0

Bene, per una struttura e le enumerazioni non sono oggetti in questo senso. Ma sì, vorrei essere un po 'più specifico: il precedente comportamento si applica alle istanze di tipi @class * importati * da Objective-C –

+0

In realtà ** no ** La classe Swift è una classe Objective-C. Si creano classi Objective-C creando sottoclassi di una classe Objective-C, come 'NSObject', o dichiarando la classe preceduta da' @ objc'. – Rivera

0

Prova:

dump(object) 

Maggiori informazioni here