I have an object that is being retained more than necessary (most likely due to a property that is strong instead of weak). Big codebase, so it\'s
This solution was somewhat helpful for me. It basically uses method swizzling to tricks the ARC compiler into thinking you're not overriding retain and release.
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class cls = [self class];
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
SEL originalSelector1 = NSSelectorFromString(@"retain");
SEL swizzledSelector1 = NSSelectorFromString(@"myretain");
SEL originalSelector2 = NSSelectorFromString(@"release");
SEL swizzledSelector2 = NSSelectorFromString(@"myrelease");
Method originalMethod1 = class_getInstanceMethod(cls, originalSelector1);
Method swizzledMethod1 = class_getInstanceMethod(cls, swizzledSelector1);
Method originalMethod2 = class_getInstanceMethod(cls, originalSelector2);
Method swizzledMethod2 = class_getInstanceMethod(cls, swizzledSelector2);
BOOL didAddMethod1 =
class_addMethod(cls,
originalSelector1,
method_getImplementation(swizzledMethod1),
method_getTypeEncoding(swizzledMethod1));
if (didAddMethod1) {
class_replaceMethod(cls,
swizzledSelector1,
method_getImplementation(originalMethod1),
method_getTypeEncoding(originalMethod1));
} else {
method_exchangeImplementations(originalMethod1, swizzledMethod1);
}
BOOL didAddMethod2 =
class_addMethod(cls,
originalSelector2,
method_getImplementation(swizzledMethod2),
method_getTypeEncoding(swizzledMethod2));
if (didAddMethod2) {
class_replaceMethod(cls,
swizzledSelector2,
method_getImplementation(originalMethod2),
method_getTypeEncoding(originalMethod2));
} else {
method_exchangeImplementations(originalMethod2, swizzledMethod2);
}
});
}
-(id)myretain {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
NSLog(@"tracking retain now %d",(int)[self performSelector:NSSelectorFromString(@"retainCount")]);
SEL selector = NSSelectorFromString(@"myretain");
return [self performSelector:selector withObject:nil];
#pragma clang diagnostic pop
}
-(id)myrelease {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
NSLog(@"tracking release now %d",(int)[self performSelector:NSSelectorFromString(@"retainCount")]);
SEL selector = NSSelectorFromString(@"myrelease");
return [self performSelector:selector withObject:nil];
#pragma clang diagnostic pop
}