Obtenir le nombre d'instances d'une class spécifique dans Objectice C / IOS

À des fins d'assurance qualité, je souhaite m'assurer que les instances de classs spécifiques ont été désallouées correctement (le nombre réel d'instances est donc suffisant). J'ai regardé dans la reference d'exécution Objective C, mais je n'ai pas trouvé la fonction appropriée. J'ai vérifié des questions similaires mais je n'ai pas trouvé de réponse satisfaisante.

Edit J'ai pris la maquette de TheCodingArt et l'ai complétée, le résultat peut être obtenu sur https://www.generomobile.de/gmi/allocchecker.m La difficulté a été d'échanger dealloc car ARC interdit de passer le sélecteur de dealloc pour swizzling. Je suis tombé sur cet intéressant tutoriel de swizzling à http://defagos.github.io/yet_another_article_about_method_swizzling/ NSSsortingng et d'autres clusters de class ne sont évidemment pas libérés par dealloc comme on peut le voir dans l'exemple. Mais pour mes propres cours, cela fonctionne sur notre projet IOS actuel et donne des ins- criptions intéressantes.

Par request, j'ai mocké une catégorie qui gardera le count des objects alloués en utilisant la méthode swizzling et un singleton. C'était une maquette rapide, donc il y a quelques problèmes avec cela (l'une étant que l'initialisation de tout ce qui est contenu dans la class de stockage provoquera une boucle infinie). Rappelez-vous, c'est pour garder la trace de nombreux objects et ne devrait pas être utilisé dans un environnement de production. La meilleure méthodologie globale est d'utiliser l'outil d'instruments.

#import "NSObject+Initializer.h" #import <objc/runtime.h> @interface ObjectCounter : NSObject + (instancetype)sharedObjectCounter; @property (strong, nonatomic) NSMutableDictionary *objectCounterDictionary; @end @implementation ObjectCounter + (instancetype)sharedObjectCounter { static ObjectCounter *objectCounter; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ objectCounter = [ObjectCounter new]; objectCounter.objectCounterDictionary = [NSMutableDictionary new]; }); return objectCounter; } @end @implementation NSObject (Initializer) + (NSNumber *)initializedCount { NSLog(@"Dict: %@", [ObjectCounter sharedObjectCounter].objectCounterDictionary); return [ObjectCounter sharedObjectCounter].objectCounterDictionary[NSSsortingngFromClass([self class])]; } + (id)alloc_swizzled { NSLog(@"Swizzled"); NSSsortingng *className = NSSsortingngFromClass([self class]); if (![className isEqualToSsortingng:NSSsortingngFromClass([NSMutableDictionary class])] && ![className isEqualToSsortingng:NSSsortingngFromClass([ObjectCounter class])]) { ObjectCounter *counter = [ObjectCounter sharedObjectCounter]; NSMutableDictionary *objectDictionary = counter.objectCounterDictionary; NSNumber *count = objectDictionary[className]; count = count ? @(count.integerValue + 1) : @0; objectDictionary[className] = count; } return [self alloc_swizzled]; } + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(alloc); SEL swizzledSelector = @selector(alloc_swizzled); Method originalMethod = class_getClassMethod(class, originalSelector); Method swizzledMethod = class_getClassMethod(class, swizzledSelector); BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } 

Une solution consiste à installer un countur statique dans votre file. Incrémentez le countur dans la méthode init désignée et décrémentez le countur dans la méthode dealloc . Fournissez une méthode de class pour lire la valeur de comptage.

Ne faites pas cela en règle générale. Cela ne devrait être fait que pour les tests.

Disons que vous voulez suivre le nombre d'instances de SomeClass . Tu peux faire:

SomeClass.h

 @interface SomeClass : NSObject + (NSInteger)instanceCount; // everything else you need @end 

SomeClass.m

 @import "SomeClass.h" static NSInteger instanceCount = 0; @implementation SomeClass - (instancetype)init { self = [super init]; if (self) { instanceCount++; // everything else you need } return self; } // all your other code + (NSInteger)instanceCount { return instanceCount; } - (void)dealloc { instanceCount--; } @end 

Vous pouvez get un nombre sans sous-class en ajoutant une catégorie et en allouant l'allocation, Ceci est vraiment hacky mais c'est bon pour le test et bon pour les classs que vous ne possédez pas. Je n'ai aucune idée si cela fonctionnerait sans ARC.

 @implementation UILabel (LableCounter) static NSInteger labelCount = 0; + (id)alloc { labelCount++; return [super alloc]; } -(void)dealloc{ labelCount--; } @end