ios - programming - swift reference
LLDB(Swift): conversión de dirección sin formato en tipo utilizable (11)
¿Hay un comando LLDB que puede convertir una dirección sin procesar en una clase Swift utilizable?
Por ejemplo:
(lldb) po 0x7df67c50 as MKPinAnnotationView
Sé que esta dirección apunta a un MKPinAnnotationView, pero no está en un marco que pueda seleccionar. Pero, quiero convertir la dirección sin procesar en un MKPinAnnotationView para poder examinar sus propiedades. es posible?
A partir de Xcode 8 / Swift 3, esto es lo que funcionó para mí. (Esto se basa en la respuesta de @ sfaxon ).
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)
Bajo Xcode 8.2.1 y Swift 3, el comando lldb po o p no funcionará con la variable escrita. Deberá usar el comando rápido print para examinar las propiedades de la instancia del objeto escrito. (¡Gracias a la respuesta de cbowns !) Por ejemplo:
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
(lldb) expr -l Swift -- print($pin.alpha)
El formato lldb para la
expression
parece haber cambiado en Xcode 7.3.
Lo siguiente me ayudó a comenzar:
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $view = unsafeBitCast(0x7fb75d8349c0, UIView.self)
Gracias a todas las respuestas anteriores, unsafeBitCast también funciona bien con la aplicación Xcode 8.3.2 / Swift 3 / macOS / Cocoa.
Memorizar una dirección de instancia actual
(lldb) p tabView.controlTint
(NSControlTint) $R10 = defaultControlTint
(lldb) p self
(LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 {
.....
Más tarde, examínelos
(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
(NSControlTint) $R20 = graphiteControlTint
(lldb) p $R11.tabView.controlTint
(NSControlTint) $R21 = graphiteControlTint
Si sucede algo como esto
(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''
asegúrese de elegir uno de los marcos de pila del código fuente de Swift en lugar del ensamblador.
Es probable que suceda cuando la aplicación se detuvo haciendo clic en el botón Pausa o se detuvo con una excepción. Al elegir un marco de pila en consecuencia, deje que lldb infiera un lenguaje de programación adecuado.
La forma más fácil, rápida 4
expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
La respuesta de @Xi Chen funciona perfectamente cuando su sesión LLDB se inició en un contexto Swift. Sin embargo, en algunos casos puede haberse detenido en un punto de interrupción fuera de un contexto Swift; por ejemplo, cuando es un punto de interrupción simbólico para la API Objective-C.
error: unknown type name ''let''
error: use of undeclared identifier ''unsafeBitCast''
En ese caso, deberá hacerlo a la antigua usanza Objective-C:
e MKPinAnnotationView *$pin = (MKPinAnnotationView *)0x7df67c50
y ahora puedes usar
$pin
como lo harías.
Me tomó más tiempo darme cuenta de que me gustaría admitirlo. Es similar a la respuesta de @afinlayson, pero con una mejor explicación (¡espero!) Y sintaxis fija
Si desea verificar las propiedades de un objeto utilizando el depurador de jerarquía de vistas de Xcode, esto funcionará: está en contexto objc de forma predeterminada, por lo que deberá cambiarlo a contexto Swift
- Primero importe su proyecto (si desea utilizar algunas de las clases definidas allí)
expr -l Swift -- import <YOUR PROJECT NAME>
- Transmita el objeto usando su dirección de memoria a la clase que desee
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: <YOUR PROJECT NAME>.<YOUR CUSTOM CLASS NAME>.self)
- Acceda a cualquier valor que desee del objeto
expr -l Swift -- print($vc.<PROPERTY NAME>)
Ejemplo:
expr -l Swift -- import Football
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)
expr -l Swift -- print($vc.velocity)
Para clases personalizadas necesita importar su proyecto
expr -l Swift -- import MyTestProject
expr -l Swift -- let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self)
expr -l Swift -- print($vc.view)
Puede usar la función
unsafeBitCast
de Swift para emitir una dirección a una instancia de objeto:
(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self)
(lldb) po $pin
Entonces puede trabajar con
$pin
como de costumbre: acceder a propiedades, métodos de llamada, etc.
Consulte este artículo para obtener más información: Volcado rápido de memoria .
Versión Objective-C
po ((MKPinAnnotationView *)0x7df67c50).alpha
po
es un alias, lo que significa que se puede anular.
Puede anular
po
manejando direcciones hexadecimales usando objc:
command regex po
s/(0x[[:xdigit:]]+)/expression -l objc -O -- %1/
s/(.+)/expression -O -- %1/
Para ver qué efecto tiene esto, puede decirle a lldb que expanda estos alias:
(lldb) settings set interpreter.expand-regex-aliases true
También he creado
https://github.com/kastiglione/swift_po
, que es un sustituto
po
para Swift.
Maneja direcciones de objetos y tiene algunas otras mejoras también.