开发者

Callback method before deallocating any Object

Is there any way to call a method before deallocating any NSObject Class object.

or

Is it possible to writing custom dealloc method for NSObject Class so that

we can call any method before deallocating that object?

As garbage collector is not available for iPhone, I wants to create small framework which handles memory leak at runtime & create a log files for leaks (I known that there is instrument that identify the leaks but still for R&D and don't want to implement Garbag开发者_运维技巧e Collector algo).

We are trying to maintain a list of allocated object.

for example:

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];

but when any object get deallocate then I want to 1st look, whether address of that object is present in dictionary or not. If address present then remove it from dictionary.

Please guide me, whether it's possible or not.

Thanks


Here’s an example gist showing how to swizzle the dealloc method, if that’s what you are after. Main part of the code:

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

As Bavarious says, this is dark magic and I wouldn’t use it in production, ever.


You might be able to use objc_setAssociatedObject to track the lifespan of the object. Something like this:

Header:

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

Implementation:

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

This takes advantage of the fact that associated objects are released when the objects they are associated with are dealloced. It won't work with NSZombies enabled, and it may break if you're using ARC or something else which messes about with retain counts. I wouldn't count on being able to use the object in question during the callback, but its address should still be OK and that's what you seem to need.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜