出于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项目并提供一些有趣的知识。
答案 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