在解除分配任何NSObject类对象之前,有没有办法调用方法。
或
是否可以为NSObject类编写自定义dealloc方法以便使用 我们可以在解除分配该对象之前调用任何方法吗?
由于垃圾收集器不适用于iPhone,我想创建一个在运行时处理内存泄漏的小框架。为泄漏创建一个日志文件(我知道有一个工具可以识别泄漏但仍然用于R& D并且不想实现垃圾收集器算法)。
我们正在尝试维护已分配对象的列表。
例如:
A *a=[[A alloc]init];
NSString * veribaleAddress=[NSString stringWithFormat:@"%p",&a];
NSString *allocatedMemoryAddress=[NSString stringWithFormat:@"%p",a];
// Global dictionary for maintaining a list of object NSMutableDictionary *objects;
[objects setValue: allocatedMemoryAddress forKey: veribaleAddress];
但是当任何对象获得解除分配时,我想先看一下,该对象的地址是否存在于字典中。如果地址存在,则将其从字典中删除。
请指导我,无论是否可能。
由于
答案 0 :(得分:9)
这是一个example gist,展示如何swizzle dealloc
方法,如果这就是你所追求的。代码的主要部分:
void swizzle(Class c, SEL orig, SEL patch)
{
Method origMethod = class_getInstanceMethod(c, orig);
Method patchMethod = class_getInstanceMethod(c, patch);
BOOL added = class_addMethod(c, orig,
method_getImplementation(patchMethod),
method_getTypeEncoding(patchMethod));
if (added) {
class_replaceMethod(c, patch,
method_getImplementation(origMethod),
method_getTypeEncoding(origMethod));
return;
}
method_exchangeImplementations(origMethod, patchMethod);
}
id swizzledDealloc(id self, SEL _cmd)
{
// …whatever…
return self;
}
const SEL deallocSel = @selector(dealloc);
// If using ARC, try:
// const SEL deallocSel = NSSelectorFromString(@"dealloc");
const SEL swizzledSel = @selector(swizzledDealloc);
class_addMethod(c, swizzledSel, (IMP) swizzledDealloc, "@@:");
swizzle(c, deallocSel, swizzledSel);
正如巴伐利亚所说,这是黑魔法,我不会在生产中使用它。
答案 1 :(得分:3)
您可以使用objc_setAssociatedObject来跟踪对象的生命周期。像这样:
部首:
// SGBObjectTracker.h
typedef void (^SGBObjectTrackerCallback)(id trackedObject);
@interface SGBObjectTracker : NSObject
@property (nonatomic, assign) id trackedObject;
@property (nonatomic, copy) SGBObjectTrackerCallback callback;
+(void) trackObject:(id)object withCallback:(SGBObjectTrackerCallback)callback;
@end
实现:
// SGBObjectTracker.m
#import "SGBObjectTracker.h"
#import <objc/runtime.h>
@implementation
@synthesize trackedObject, callback;
-(void) dealloc
{
callback(trackedObject);
[super dealloc];
}
+(void) trackObject:(id)object withCallback:(SGBObjectTrackerCallback)callback
{
SGBObjectTracker *tracker = [[self alloc] init];
tracker.callback = callback;
tracker.trackedObject = object;
objc_setAssociatedObject(object, _cmd, tracker, OBJC_ASSOCIATION_RETAIN);
[tracker release];
}
@end
这利用了以下事实:关联对象在与其关联的对象被释放时被释放。它不适用于NSZombies启用,如果您使用ARC或其他与保留计数混淆的东西,它可能会破坏。我不会指望在回调期间能够使用有问题的对象,但它的地址应该仍然没问题,而这正是你所需要的。