Per request, I've mocked up a category that will keep count of allocated objects using method swizzling and a singleton. This was a quick mock up, so there are a few issues with it (one being that initializing anything that is contained within the storage class will cause an infinite loop). Mind you, this is for keeping track of many objects and should not be used in a production environment. The best methodology overall is to use the instruments tool.
#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[NSStringFromClass([self class])];
}
+ (id)alloc_swizzled
{
NSLog(@"Swizzled");
NSString *className = NSStringFromClass([self class]);
if (![className isEqualToString:NSStringFromClass([NSMutableDictionary class])] && ![className isEqualToString:NSStringFromClass([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);
}
});
}