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