Find where object is retained with ARC

后端 未结 5 1475
逝去的感伤
逝去的感伤 2020-12-07 12:03

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

5条回答
  •  生来不讨喜
    2020-12-07 12:57

    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
    

    }

提交回复
热议问题