Skip to content

Instantly share code, notes, and snippets.

@zoul
Created November 11, 2010 15:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoul/672643 to your computer and use it in GitHub Desktop.
Save zoul/672643 to your computer and use it in GitHub Desktop.
Detects object deallocations. Good for testing.
// Runs given block. Returns YES if some object of class ‘c’
// was deallocated in the block. Not thread-safe.
BOOL classGetsDeallocated(Class c, void (^block)(void));
// Convenience interface that calls the function above.
// Releases object, returns YES if object was deallocated.
BOOL getsDeallocatedByReleasing(id object);
#import <objc/runtime.h>
static BOOL deallocFlag = NO;
static 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);
}
static id swizzledDealloc(id self, SEL _cmd)
{
deallocFlag = YES;
return self;
}
BOOL classGetsDeallocated(Class c, void (^block)(void))
{
const SEL deallocSel = @selector(dealloc);
const SEL swizzledSel = @selector(swizzledDealloc);
class_addMethod(c, swizzledSel, (IMP) swizzledDealloc, "@@:");
swizzle(c, deallocSel, swizzledSel);
deallocFlag = NO;
block();
swizzle(c, swizzledSel, deallocSel);
return deallocFlag;
}
// Wouldn’t this be simply [object retainCount] == 1 for all
// cases except when somebody is doing something really stupid?
BOOL getsDeallocatedByReleasing(id object)
{
return classGetsDeallocated([object class], ^{ [object release]; });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment