web-dev-qa-db-fra.com

méthode récursiveDescription dans Swift?

Est-il possible d’utiliser [self.view récursiveDescription] dans Swift? J'essaie d'utiliser cette méthode mais j'obtiens l'erreur suivante:

'UIView' does not have a member named 'recursiveDescription'

Aucune suggestion?

31
Vik Singh

Pour accéder à l'API Objective-C privée/non documentée (telle que la méthode -recursiveDescription sur UIView) à partir de Swift, vous pouvez effectuer les opérations suivantes:

  1. Créez une nouvelle catégorie Objective-C sur la classe dans laquelle la méthode privée est définie (par exemple UIView).
  2. Hit Yes si Xcode vous demande de configurer un en-tête de pontage. (Si vous avez déjà un en-tête de pontage dans votre projet, cette étape sera ignorée).
  3. Le fichier d'implémentation (.m) de la catégorie peut être supprimé.
  4. Déclarez la méthode privée dans l'en-tête de la catégorie:

    // UIView+Debugging.h
    
    @interface UIView (Debugging)
    - (id)recursiveDescription;
    @end
    

Vous pouvez maintenant définir un point d'arrêt et imprimer la description récursive dans LLDB:

po view.recursiveDescription() as NSString
8
bernhard

Si vous souhaitez afficher la hiérarchie des vues dans lldb, vous n'avez pas besoin d'ajouter de catégories ni d'en-têtes de pontage, ni rien de ce genre. Lors du débogage du code Objective-C, on utilisera généralement la commande suivante à l'invite (lldb):

po [[UIWindow keyWindow] recursiveDescription]

Si, toutefois, vous avez fait une pause dans un cadre Swift, lldb peut s'attendre à une expression Swift. Vous pouvez cependant indiquer explicitement expr (l'abréviation po appelle en réalité expression) le langage dans lequel l'expression est:

expr -l objc++ -O -- [[UIWindow keyWindow] recursiveDescription]

Les mêmes modèles se produisent dans iOS 8 lors de l'affichage de la hiérarchie du contrôleur de vue, avec:

po [UIViewController _printHierarchy]

ou, dans le cadre Swift:

expr -l objc++ -O -- [UIViewController _printHierarchy]

Dans WWDC 2018 Débogage avancé avec Xcode , ils vous suggèrent de vous écarter de cette syntaxe compliquée de expr en définissant un alias, poc, en créant un fichier texte, ~/.lldbinit, avec la ligne suivante:

command alias poc expression -l objc -O --

Ensuite, vous pouvez faire des choses comme:

poc [UIViewController _printHierarchy]

Il convient de noter que Xcode 8 a introduit le débogueur de vues (cliquez sur  view debug button ), offrant un moyen plus interactif d'analyser la hiérarchie des vues, éliminant en grande partie le besoin de LLDB recursiveDescription de la hiérarchie des vues. Pour plus d'informations, voir WWDC 2016 video Débogage visuel avec Xcode . Certes, nous devons parfois nous rabattre sur la technique recursiveDescription présentée ci-dessus, mais la plupart du temps, le débogueur de vues en fait un processus beaucoup plus naturel et intuitif.

Et dans Xcode 9, ils ont développé ce débogueur de vues, de sorte qu'il inclut désormais les contrôleurs de vues appropriés:

 enter image description here

80
Rob
po view.value(forKey: "recursiveDescription")!
16
rob mayoff

Commencez par ajouter une catégorie @interface sans @implementation dans votre en-tête de pontage.

@interface UIView (Debug)
- (id)recursiveDescription;
- (id)_autolayoutTrace;  // This one is even sweeter
@end

alors dans votre console

po self.recursiveDescription() as NSString
po self._autolayoutTrace() as NSString

La clé ici est as NSString pas as String

7
CopperCash
expression -l objc -O -- [`self.view` recursiveDescription]

Il est nécessaire de le saisir au format Objective-C car UIKit se trouve dans le framework Objective-C.

La description récursive existe uniquement à des fins de débogage. Cela ne fait pas partie de l'API publique et n'est donc pas disponible pour Swift

Et Swift est un langage strict et ne vous permet pas d’appeler des fonctions qui n’ont pas été définies de manière stricte.

Objective-C est un langage dynamique qui vous permet d’appeler des fonctions de ce type.

Nous devons donc indiquer au débogueur d'évaluer cette expression dans une syntaxe Objective-C.

Et la manière de le faire est d’utiliser expression avec l’option - l objc

-O, indiquez au débogueur que nous voulons également que la description de débogage soit identique à celle que po ferait et - pour indiquer qu'il n'y a plus d'options.

Nous devons mettre la vue [self.view] entre les ticks arrière.

[`self.view`]

Les ticks en arrière sont comme une étape préalable au processus qui dit, évaluez le contenu de ceci dans le cadre actuel et insérez le résultat, puis nous pourrons évaluer le reste.

Ma réponse est tirée du débogage avancé de la session 412 de la WWDC 2018 avec Xcode et lldb.

3
ManuelMB

Ajoutez à l'en-tête de pontage une déclaration d'une catégorie de UIView avec cette méthode.

1
newacct

Construire sur @Rob Mayoff'srépondre :

extension UIView {

   /**
    Wrapper for useful debugging description of view hierarchy
   */
   var recursiveDescription: NSString {
       return value(forKey: "recursiveDescription") as! NSString
   }

}
0
Chuck Krutsinger