Based on a code I've found in this blog post, I've wrote a template for subclassing somebody else's class to print out the allocation history.
Here's how it looks:
This file contains 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
#define SYNTESIZE_TRACE(X) \ | |
@interface Trace##X : X { \ | |
} \ | |
@end \ | |
\ | |
@implementation Trace##X\ | |
\ | |
- (id)retain {\ | |
NSUInteger oldRetainCount = [super retainCount];\ | |
id result = [super retain];\ | |
NSUInteger newRetainCount = [super retainCount];\ | |
NSLog(@"%@<%@> ++retainCount: %d => %d\n", [self class] , self, oldRetainCount, newRetainCount);\ | |
NSLog(@"%@\n", [NSThread callStackSymbols] );\ | |
return result;\ | |
}\ | |
\ | |
- (void)release {\ | |
NSUInteger oldRetainCount = [super retainCount];\ | |
BOOL gonnaDealloc = oldRetainCount == 1;\ | |
if (gonnaDealloc) {\ | |
NSLog(@"%@<%@> --retainCount: 1 => 0 (gonna dealloc)\n", [self class] , self);\ | |
NSLog(@"%@\n", [NSThread callStackSymbols] );\ | |
}\ | |
[super release];\ | |
if (!gonnaDealloc) {\ | |
NSUInteger newRetainCount = [super retainCount];\ | |
NSLog(@"%@<%@> --retainCount: %d => %d\n", [self class] , self, oldRetainCount, newRetainCount);\ | |
NSLog(@"%@\n", [NSThread callStackSymbols] );\ | |
}\ | |
}\ | |
\ | |
@end |
And here's how you use it (in this example, I want to track AVPlayer):
SYNTESIZE_TRACE(AVPlayer)
AVPlayer* p = [[TraceAVPlayer alloc] init];
All done. Now, while running, you'll get a record of all retainCount modifications, with their stack trace.
No comments:
Post a Comment