2015-04-04 20 views
33

Esiste un comando LLDB in grado di trasmettere un indirizzo raw in una classe Swift utilizzabile?LLDB (Swift): castare l'indirizzo grezzo in tipo utilizzabile

Ad esempio:

(lldb) po 0x7df67c50 as MKPinAnnotationView 

So che questo indirizzo indica un MKPinAnnotationView, ma non è in una cornice che posso selezionare. Ma, voglio trasmettere l'indirizzo raw in un MKPinAnnotationView in modo che possa esaminare le sue proprietà. È possibile?

risposta

34

Sotto xCode 8.2.1 e Swift 3, il comando lldb po o p non funzionerà con la variabile digitato. Sarà necessario utilizzare il comando rapido stampa per esaminare le proprietà dell'istanza dell'oggetto digitato. (Grazie a cbowns's answer!) Es .:

(lldb) expr -l Swift -- import UIKit 
(lldb) expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self) 
(lldb) expr -l Swift -- print($pin.alpha) 
+2

Questo davvero non dovrebbe essere così difficile –

+0

Questo è stato un po 'contro-intuitivo. Pensavo di non aver bisogno di digitare '(lldb)' nella mia console. Ma non ha funzionato senza quello. – Honey

30

È possibile utilizzare la funzione di Swift unsafeBitCast per lanciare un indirizzo ad un'istanza di un oggetto:

(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self) 
(lldb) po $pin 

Poi si può lavorare con $pin come al solito - proprietà di accesso, i metodi di chiamata, ecc

Partenza questo articolo per ulteriori informazioni: Swift Memory Dumping.

+0

Per la prima dichiarazione penso che hai dimenticato il 'expr' o 'espressione'. Altrimenti funziona alla grande! – jarrodparkes

+0

Grazie ... risolto! Errore – gregheo

+2

"Errore": uso dell'identificatore non dichiarato 'unsafeBitCast' "in Xcode 7.2. – devios1

17

Il formato lldb per expression sembra essere cambiato in XCode 7.3. Quello che segue mi ha fatto iniziare:

(lldb) expr -l Swift -- import UIKit 
(lldb) expr -l Swift -- let $view = unsafeBitCast(0x7fb75d8349c0, UIView.self) 
7

A partire da Xcode 8/Swift 3, ecco cosa ha funzionato per me. (Questo è basato fuori @sfaxon's answer.)

(lldb) expr -l Swift -- import UIKit 
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self) 
2

Grazie a tutte le risposte di cui sopra, unsafeBitCast funziona bene anche con Xcode 8.3.2/Swift 3/MacOS/Cocoa Application.

Memorizzare un indirizzo di istanza corrente

(lldb) p tabView.controlTint 
(NSControlTint) $R10 = defaultControlTint 

(lldb) p self 
(LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 { 
..... 

Più tardi, esaminarli

(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint 
(NSControlTint) $R20 = graphiteControlTint 

(lldb) p $R11.tabView.controlTint 
(NSControlTint) $R21 = graphiteControlTint 

Se qualcosa del genere accade

(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint 
error: use of undeclared identifier 'to' 

(lldb) p $R11.tabView.controlTint 
error: use of undeclared identifier '$R11' 

assicurarsi che scegliere una delle stack frame di Swift codice sorgente piuttosto che assemblatore uno.

E 'probabile che accada quando l'applicazione è stata messa in pausa facendo clic su un pulsante di pausa o fermata con un'eccezione. Scegliendo un frame di conseguenza, consenti a lldb di dedicare un linguaggio di programmazione corretto.

4

Per le classi personalizzate è necessario importare il progetto

expr -l Swift -- import MyTestProject 
expr -l Swift -- let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self) 
expr -l Swift -- print($vc.view)