解除分配任何Object之前的回调方法

Abh*_*eet 7 iphone cocoa cocoa-touch objective-c

有没有办法在解除分配任何NSObject类对象之前调用方法.

要么

是否有可能为NSObject类编写自定义dealloc方法,以便
我们可以在释放该对象之前调用任何方法?

由于垃圾收集器不适用于iPhone,我想创建一个小框架,在运行时处理内存泄漏并创建泄漏日志文件(我知道有一种工具可以识别泄漏但仍然用于研发而不想实现垃圾收集器算法).

我们正在尝试维护已分配对象的列表.

例如:

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];
Run Code Online (Sandbox Code Playgroud)

但是当任何对象被释放时,我想先看一下,该对象的地址是否存在于字典中.如果地址存在,则将其从字典中删除.

请指导我,无论是否可能.

谢谢

zou*_*oul 9

下面是一个例子要点展示如何调配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);
Run Code Online (Sandbox Code Playgroud)

正如巴伐利亚所说,这是黑魔法,我永远不会在生产中使用它.


Sim*_*mon 5

您也许可以使用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
Run Code Online (Sandbox Code Playgroud)

执行:

// 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
Run Code Online (Sandbox Code Playgroud)

这利用了当关联对象被解除分配时关联对象被释放的事实。它不会在启用 NSZombies 的情况下工作,并且如果您使用 ARC 或其他与保留计数有关的东西,它可能会中断。我不指望能够在回调期间使用有问题的对象,但它的地址应该仍然可以,这就是您似乎需要的。

  • 关联对象在父对象的 ivars 被清除后被释放,因此它对于例如取消注册 KVO 没有用。 (4认同)