获取Objectice C / IOS中特定类的实例计数

时间:2015-05-28 14:21:17

标签: ios objective-c

出于QA目的,我想确保特定类的实例已被正确释放(因此实际的实例数量就足够了)。我查看了Objective C运行时引用,但是找不到合适的函数。我检查了类似的问题,但没有找到令人满意的答案。

修改 我拿了TheCodingArt的模型并完成了它,结果可以在 https://www.generomobile.de/gmi/allocchecker.m 由于ARC禁止传递dealloc的选择器进行调配,因此难以调动dealloc。我在http://defagos.github.io/yet_another_article_about_method_swizzling/偶然发现了这个有趣的混音教程 显然,NSEtring和其他类集群不会被dealloc释放,正如人们在样本中看到的那样。但是对于我自己的课程,它适用于我们当前的IOS项目并提供一些有趣的知识。

3 个答案:

答案 0 :(得分:3)

一种解决方案是在.m文件中设置静态计数器。在指定的init方法中递增计数器,并在dealloc方法中递减计数器。提供一个类方法来读取计数值。

不要这样做。这只应该用于测试。

假设您要跟踪SomeClass的实例数。你可以这样做:

<强> 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

答案 1 :(得分:2)

根据请求,我已经模拟了一个类别,该类别将使用方法调配和单例来保持已分配对象的数量。这是一个快速模拟,所以它有一些问题(一个是初始化存储类中包含的任何内容将导致无限循环)。请注意,这是为了跟踪许多对象,不应在生产环境中使用。总体上最好的方法是使用仪器工具。

#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);
        }
    });
}

答案 2 :(得分:0)

你可以通过添加一个类别和重写alloc来获得一个没有子类的计数。这真的很糟糕,但它适用于测试,对你不拥有的类很有用。如果没有ARC,我不知道这是否可行。

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