Mise à jour : cet ancien plugin Xcode a été réorganisé en un package Swift pour une utilisation dans d'autres applications. Utilisez le produit Xprobe
dans les applications client et le produit XprobeUI
côté serveur.
Le XprobePlugin vous donne une vue des objets à l'intérieur de votre application soit en détail jusqu'au niveau des ivars, soit globalement sous forme de graphique des principaux objets et de la façon dont ils sont connectés. Cet affichage peut être animé en temps réel, mettant en évidence en rouge les objets au fur et à mesure qu'ils reçoivent des messages et les chemins par lesquels circulent les messages. Cela se fait automatiquement en effectuant un "balayage" pour trouver tous les objets référencés par un ensemble de graines, les objets auxquels ils font référence, les objets auxquels ils font référence et ainsi de suite pour construire la liste des objets vivants qui peuvent être affichés dans Xcode. :
Dans le simulateur, le balayeur de mémoire est chargé à partir d'un bundle à l'intérieur du plugin à l'aide de lldb, ne nécessitant aucune modification de la source du projet de l'application. Pour utiliser le plugin, créez ce projet et redémarrez Xcode. Une fois votre application en cours d'exécution, utilisez l'élément de menu "Product/Xprobe/Load" pour charger la vue initiale du balayage de la mémoire de votre application. Si vous êtes un développeur de plugins, vous utilisez "Product/Xprobe/Xcode" pour inspecter les objets de l'application Xcode elle-même.
Vous pouvez ensuite filtrer les objets répertoriés dans l'application ou leurs méthodes à l'aide d'un modèle. S'il n'y a aucun objet correspondant au modèle et qu'il s'agit d'un nom de classe, il sera affiché. Les modèles préfixés par « + » ou « - » rechercheront dans toutes les classes liées à l'application les méthodes correspondant au modèle. Un pointeur brut préfixé par « 0x » peut être saisi pour inspecter un objet passé en argument à une trace. Vous pouvez également saisir un « chemin » d'objet commençant par « graine ». à partir des chemins enregistrés lorsque vous parcourez votre application afin que vous puissiez facilement retrouver votre chemin vers les objets.
Si le plugin injectionforxcode est installé, Xprobe vous permettra d'évaluer Objective-C ou Swift par rapport à une instance sélectionnée pour laquelle vous disposez de la source pour enregistrer ou modifier tout aspect de l'état de l'objet au moment de l'exécution.
Xprobe.mm peut désormais capturer votre application dans un fichier HTML autonome en cas d'erreur. Cela effectue un balayage et peut documenter l'état de votre application au moment où l'erreur s'est produite pour une analyse ultérieure. Un exemple de fichier d'instantané pour un exemple de projet ReactNative "TickTackToe" peut être consulté ici.
Pour prendre un instantané, incluez Xprobe.mm dans votre application et utilisez l'appel suivant :
[Xprobe snapshot: @" /path/to/snapshot.html.gz " seeds: @[app delegate, rootViewController]];
Si vous rencontrez des difficultés, vous pouvez modifier le modèle des noms de classe à ne pas capturer avec un argument supplémentaire exclusion:(NSString *)pattern. La valeur par défaut pour cela est :
@" ^(?:UI|NS((Object|URL|Proxy)$|Text|Layout|Index|.*(Map|Data|Font))|Web|WAK|SwiftObject|XC|IDE|DVT|Xcode3|IB|VK) "
Les fonctionnalités restantes sont plus facilement présentées sous la forme d’une série de puces :
Cliquez sur le lien d'un objet pour afficher son contenu ivar.
Cliquez à nouveau sur le lien pour fermer la vue détaillée.
Cliquez sur le lien de la superclasse pour voir ses ivars
Cliquez sur un nom ivar pour actualiser sa valeur depuis l'application
Cliquez sur une valeur ivar pour la modifier et définir sa valeur dans l'application
Les propriétés, méthodes et tous les protocoles de la classe peuvent être visualisés.
Les listes de méthodes peuvent être recherchées (et trouver également des méthodes de superclasse)
Utilisez le lien « trace » pour commencer à enregistrer les appels aux méthodes sur cette instance.
Pour voir toutes les méthodes tracées pour un objet, cliquez sur trace par rapport à chaque classe.
La sortie de trace peut être filtrée à l'aide d'une expression régulière
Le lien des sous-vues affichera de manière récursive l’arborescence des sous-vues sous une vue.
Le lien "Rendu" capturera une image lorsque l'objet est une vue.
Le lien frères et sœurs affichera tous les objets trouvés qui partagent la classe de l'objet.
Actualisez la liste d'objets en tapant Entrée dans le champ de recherche pour forcer un nouveau balayage.
En appuyant sur le bouton Graphique, vous ouvrirez la vue récapitulative des objets les plus importants et de tous les objets "kit" directement liés à eux issus du dernier balayage.
L'objet est représenté sous forme de carré s'il s'agit d'une vue (répond aux "sous-vues".)
L'affichage graphique nécessite une installation de "Graphviz/dot" sur votre ordinateur.
Cliquez sur un objet pour afficher son contenu actuel, comme indiqué ci-dessus.
Un filtrage différent des objets à inclure peut être appliqué.
« Animer les messages » met une trace sur les objets en les faisant afficher « rouge » lorsqu'ils reçoivent un message.
Les graphiques peuvent être exportés au format Graphviz ou .png pour l'impression.
Hélas, le support de Swift est limité pour le moment car ivar_getTypeEncoding() renvoie NULL pour les champs ivar les empêchant de participer au "sweep".
Xprobe fonctionne en chargeant un bundle dans le simulateur qui se connecte à Xcode lorsqu'il est chargé. Une application fait connaître sa liste de nœuds de départ à Xprobe en implémentant la catégorie suivante :
@implementation Xprobe (Seeding)
+ ( NSArray *)xprobeSeeds {
UIApplication *app = [UIApplication sharedApplication ];
NSMutableArray *seeds = [ NSMutableArray arrayWithObject: app];
[seeds addObjectsFromArray: [app windows ]];
// support for cocos2d
Class ccDirectorClass = NSClassFromString ( @" CCDirector " );
CCDirector *ccDirector = [ccDirectorClass sharedDirector ];
if ( ccDirector )
[seeds addObject: ccDirector];
return seeds;
}
@end
Ou pour OSX :
+ ( NSArray *)xprobeSeeds {
NSApplication *app = [ NSApplication sharedApplication ];
NSMutableArray *seeds = [[app windows ] mutableCopy ];
if ( app. delegate )
[seeds insertObject: app.delegate atIndex: 0 ];
return seeds;
}
Une fois qu'une application est initialisée, appelez [Xprobe connectTo:"your.ip.address" retentionObjects:YES] pour vous connecter au serveur TCP exécuté dans Xcode. L'argument RetainObjects: spécifie s'il faut conserver les objets trouvés lors du balayage. Cela rendra Xprobe plus fiable, mais cela affectera les cycles de vie des objets dans votre application. Après cela, appelez [Xprobe search:@""] pour effectuer le balayage initial en commençant par ces objets à la recherche d'objets racine. Chaque fois que "search:" est appelé ou que le filtre de classe d'objet est modifié, le balayage est à nouveau effectué. L'application devra être construite avec Xprobe et Xtrace.{h,mm}.
À notre époque de jolis pointeurs "forts" et "faibles", le balayage semble très fiable si les objets sont visibles d'une manière ou d'une autre par les graines. Certaines classes héritées ne se comportent pas bien et utilisent des propriétés « assigner » qui peuvent contenir des pointeurs vers des objets désalloués. Pour éviter de balayer les ivars de ces classes, Xprobe dispose d'un filtre d'exclusion qui peut être remplacé (avec un avertissement) dans une catégorie :
static NSString *swiftPrefix = @" _TtC " ;
@implementation Xprobe (ExclusionOverride)
+ ( BOOL )xprobeExclude:( NSString *)className {
static NSRegularExpression *excluded;
if ( !excluded )
excluded = [ NSRegularExpression xsimpleRegexp: @" ^(_|NS|XC|IDE|DVT|Xcode3|IB|VK|WebHistory) " ];
return [excluded xmatches: className] && ![className hasPrefix: swiftPrefix];
}
@end
Ces exclusions permettent à Xprobe de fonctionner proprement dans Xcode lui-même, ce qui est pratique si vous êtes un développeur de plugins. Pour toute suggestion ou commentaire, vous pouvez contacter l’auteur sur xprobe à johnholdsworth.com. Les versions majeures seront annoncées sur Twitter @Injection4Xcode.
Avec Swift 2.3+, Xprobe n'est plus capable d'analyser les ivars qui n'ont pas de propriétés, c'est-à-dire les classes qui n'héritent pas de NSObject.
Xprobe.{h,mm} - fonctionnalité de base de Xprobe requise pour les instantanés IvarAccess.h - routines requises pour accéder aux classes ivars par nom Xprobe+Service.mm - service interactif facultatif se connectant à Xcode
Copyright (c) 2014-5 John Holdsworth. Sous licence pour le téléchargement, la modification et toute utilisation pendant le développement d'applications Objectice-C, la redistribution ne peut se faire que via un github de dépôt public, incluant toutefois cet avis de droit d'auteur. Pour une redistribution binaire avec votre application, contactez-nous !
Cette version inclut une version très légèrement modifiée de l'excellente bibliothèque canviz pour restituer des fichiers "dot" dans un canevas HTML soumis à une licence MIT. Les changements consistent à transmettre l'ID du nœud à la balise d'étiquette du nœud (ligne 212), à inverser le rendu des nœuds et des lignes les reliant (ligne 406) et à stocker les chemins de bord afin qu'ils puissent être colorés (ligne 66 et 303) dans "canviz-0.1/canviz.js".
Il inclut désormais également l'éditeur JavaScript CodeMirror pour le code à évaluer par injection sous licence MIT.
LE LOGICIEL EST FOURNI « EN L'ÉTAT », SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS MAIS SANS LIMITATION LES GARANTIES DE QUALITÉ MARCHANDE, D'ADAPTATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS OU LES TITULAIRES DES DROITS D'AUTEUR NE SERONT RESPONSABLES DE TOUTE RÉCLAMATION, DOMMAGES OU AUTRE RESPONSABILITÉ, QUE CE SOIT DANS UNE ACTION CONTRACTUELLE, DÉLIT OU AUTRE, DÉCOULANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRANSACTIONS DANS LE LOGICIEL.