Created
November 11, 2010 15:33
-
-
Save zoul/672643 to your computer and use it in GitHub Desktop.
Detects object deallocations. Good for testing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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