ARC下会导致内存泄漏的情况

时间:2022-12-11 20:57:50

ARC下会导致内存泄漏的情况:

1、循环参照

A有个属性参照B,B有个属性参照A,如果都是strong参照的话,两个对象都无法释放。

这种问题常发生于把delegate声明为strong属性了。

例,

@interface SampleViewController

@property (nonatomic, strong) SampleClass *sampleClass;

@end

@interface SampleClass

@property (nonatomic, strong) SampleViewController *samoleVC;

@end 

上例中,解决办法是把SampleClass 的samoleVC属性的strong改为weak即可。

2、死循环

如果某个ViewController中有无限循环,也会导致即使ViewController对应的view关掉了,ViewController也不能被释放。

这种问题常发生于animation处理。

比如,

CATransition *transition = [CATransition animation];

transition.duration = 0.5;

tansition.repeatCount = HUGE_VALL;

[self.view.layer addAnimation:transition forKey:"myAnimation"];

 

上例中,animation重复次数设成HUGE_VALL,一个很大的数值,基本上等于无限循环了。

解决办法是,在ViewController关掉的时候,停止这个animation。

-(void)viewWillDisappear:(BOOL)animated {

    [self.view.layer removeAllAnimations];

}

3、core Foundation是不支持ARC的

在做Core Foundation与Objective-C类型转换的时候,用哪一种规则来管理对象的内存,是个值得注意的事情,这时候要用下面的类型转变:

__bridge(修饰符)

只是声明类型转变,但是不做内存管理规则的转变。

__bridge_retained(修饰符) or CFBridgingRetain(函数)


表示将指针类型转变的同时,将内存管理的责任由原来的Objective-C交给Core Foundation来处理,也就是,将ARC转变为MRC。

__bridge_transfer(修饰符) or CFBridgingRelease(函数)


这个修饰符和函数的功能和上面那个__bridge_retained相反,它表示将管理的责任由Core Foundation转交给Objective-C,即将管理方式由MRC转变为ARC。

4、像这样的底层,在ARC下,也是要做手动释放的:

    CGContextRef context = CGBitmapContextCreate(NULL, target_w, target_h, 8, 0, rgb, bmi);

    

    CGColorSpaceRelease(rgb);

    

    UIImage *pdfImage = nil;

    

    if (context != NULL) {

        CGContextDrawPDFPage(context, page);

        

        CGImageRef imageRef = CGBitmapContextCreateImage(context);

        CGContextRelease(context);

 

        pdfImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp];

        CGImageRelease(imageRef);

    } else {

       CGContextRelease(context);


    }

5、被__block修饰的属性也是强引用,在block块中使用的时候,要做相应的处理:

__block NSBlockOperation *operation = [[NSBlockOperation alloc] init];

    __weak typeof(self)weakSelf = self;

    __weak typeof(operation)weakOp = operation;

 

    MMVoidBlock thumbnailOperationBlock = ^ {

        if (!weakOp.isCancelled) {

            workerBlock();

        }

        

        [weakSelf.thumbnailOperationList removeObjectForKey:key];

    };


    [operation addExecutionBlock:thumbnailOperationBlock];


如果实在找不到问题,建议你找到泄露的那个对象,将其赋值为nil,因为ARC里面,一旦对象没有指针指向,就会马上被释放。

推荐文章:http://conradstoll.com/blog/2013/1/19/blocks-operations-and-retain-cycles.html 和 http://www.cnblogs.com/flyFreeZn/p/4264220.html 、http://www.cocoachina.com/ios/20150408/11501.html