最近通过Analyze
及Leaks
等工具对项目进行了内存泄漏问题的检测及修改,现对遇到的易造成内存泄漏的问题进行一些总结,每点中都列举了会造成内存泄漏的代码书写方式,并对其原因进行分析,最后给出了相关的解决方案。
接下来就开始进行总结:
一、 循环引用
循环引用是在iOS可能引起内存泄漏的主要原因,这类问题常见的出现在Block的使用中,由于Block会持有所使用到的变量,下面就总结下Block使用中需要注意的点:
1. 在Block中使用self
关键字
示例代码
@interface TestModel : NSObject
@property (nonatomic, copy) void(^TheBlock)(void);
@end
@implementation TestModel
@end
@interface TestViewController ()
@property (nonatomic, strong) TestModel *model;
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.model = [[TestModel alloc] init];
self.model.TheBlock = ^{
NSLog(@"TestViewController->%@", self);
};
}
@end
问题分析
此类问题为最基本的循环引用问题,即TestViewController持有TestModel,TestModel持有Block,Block持有TestViewController。
解决方案
在Block中使用weakSelf打破循环引用。
2. 在Blcok中访问对象的实例变量
示例代码
@interface TestViewController ()
@property (nonatomic, copy) NSString *foo;
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
void(^block)(void) = ^{
NSLog(@"foo->%@", _foo);
};
block();
}
@end
问题分析
该种写法不一定会造成内存泄漏,只有在TestViewController的持有链中持有block时才会造成内存泄漏。原因在于在Block中使用某个对象的实例变量时,会持有该对象。
解决方案
建议在Block中使用实例变量时显式指出self.
或weakSelf.
,通过显式指出,可以在一定程度上提示开发人员注意解决self持有问题。