Comment puis-je tracer la valeur d'une variable dans une application Swift avec LLDB?
Plus tôt, c'était comme po variable_name
Maintenant, je reçois généralement une erreur désagréable, comme:
(lldb) po a
error: <EXPR>:11:5: error: use of unresolved identifier '$__lldb_injected_self'
$__lldb_injected_self.$__lldb_wrapped_expr_2(
^
Cette erreur ressemble à ce qu'elle pourrait être parce que DWARF ne dit pas à LLDB où trouver votre "soi" objet. Compte tenu de la nature de Swift, LLDB a besoin de connaître le type de soi pour pouvoir injecter une expression dans votre portée locale. Une façon de savoir si tel est votre problème est de le faire à l'invite LLDB:
(lldb) variable de trame -L self
Vous ne verrez probablement pas d'emplacement pour cela. Il vaut la peine de déposer un rapport de bogue pour, juste pour suivre votre cas de repro spécifique
Quoi qu'il en soit, pour arriver à l'essentiel de votre question. Dans Swift, il n'y a pas de mécanisme sanctionné par le langage pour "imprimer la description" comme pour ObjC, donc bien que vous puissiez taper "po self", à moins que self ne soit de type Objective-C, vous verrez à peu près la même chose que "p self "ou même" frame variable self "vous dirait - qui est entièrement basé sur le mécanisme des formateurs de données LLDB. Si vous souhaitez vous y connecter pour personnaliser l'apparence de vos objets Swift, la référence obligatoire est: http://lldb.llvm.org/varformats.html
J'ai fait quelques tests pour comprendre comment cela fonctionne avec Swift, les résultats m'ont un peu surpris. Avec les objets ObjC po
appelle debugDescription
qui par défaut appelle description
. C’est clair. Malheureusement, la même chose ne s'applique pas lorsque vous travaillez avec les classes Swift. Je me suis concentré sur les objets plutôt que sur l'impression de variables uniques.
Pour le faire fonctionner (commande po
dans lldb
), j'ai dû remplacer la description. Ci-dessous le code que j'ai utilisé pour les tests:
class Test : NSObject
{
var name : String?
var surname : String?
override var debugDescription : String{
return "debugDescription method"
}
override var description : String {
return "description Method"
}
}
Essai:
let test = Test()
test.name = "name"
test.surname = "surname"
(lldb) po test
description Method
(lldb) p test
(DebugTest.Test) $R1 = 0x00007fce11404860 {
ObjectiveC.NSObject = {
isa = DebugTest.Test
}
name = "name"
surname = "surname"
}
(lldb) po dump(test)
▿ DebugTest.Test #0
- super: debugDescription method
▿ name: name
- Some: name
▿ surname: surname
- Some: surname
description Method
(lldb) po print(test)
description Method
Ce qui m'a surpris, c'est que po
on Swift objets appelle description
plutôt que debugDescription
qui diffère d'ObjC.
[~ # ~] modifier [~ # ~]
Pour le faire agir comme avec ObjC, votre classe doit implémenter CustomDebugStringConvertible puis po
appellera debugDescription
, qui par défaut appelle description
. La seule chose à changer dans mon exemple serait d'ajouter:
class Test : NSObject, CustomDebugStringConvertible
Vérifié avec XCode 7.0.1
et iOS SDK 9
, Swift 2.0
Je peux confirmer la même erreur, pour Xcode beta4 et la variable de cadre -L self
affiche quelque chose, mais semble pire:
: (SwiftCollectionViewSample.DetailViewController) self =
Je déposerai définitivement un bug, Enrico
17819707 Le débogueur imprime une erreur: utilisation de l'identificateur non résolu '$ __ lldb_injected_self'
Excellentes réponses sur cette page à propos de Swift par défaut pour retourner le description
lors de l'exécution de lldb) po
Si cela aide, lorsque je rencontre des erreurs avec lldb et Swift objets, j'ai toujours essayé d'être au bon endroit.
Tout d'abord, dites à lldb que vous êtes dans un contexte Swift (pas Objective-C):
(lldb) settings set target.language Swift
Ensuite, je revérifierais toujours que j'avais importé le Framework ..
lldb) exp import WebKit
(lldb) expr let $ds = unsafeBitCast(0x6000006d74b0, to: WKWebsiteDataStore.self)
(lldb) po $ds
<WKWebsiteDataStore: 0x6000006d74b0>