首先上图,感受下是什么样子的,采用了MRC
image.png-
instrument如下图
image.png
- 初始化控制器
SubViewController * vc = [[SubViewController alloc] init];
vc.view.backgroundColor = [UIColor redColor];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
- 控制器实现文件
@interface SubViewController ()
@property (nonatomic, strong)NSMutableArray * arrayMTest;
@end
@implementation SubViewController
- (void)dealloc{
[super dealloc];
NSLog(@"%s",__func__);
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//release test
NSMutableArray * tempArray = [NSMutableArray new];
self.arrayMTest = tempArray;
// self.arrayMTest = [NSMutableArray new];这种写法需要 [_arrayMTest release];
for (NSInteger i = 0; i<10000;i++ ) {
PeopleModel * people1 = [[PeopleModel alloc] init];
people1.name = @"zhang";
people1.age = 1;
[_arrayMTest addObject:people1];
[people1 release];
}
[tempArray release];
}
*********** PeopleModel实现**********
@interface PeopleModel : NSObject
/** name */
@property (nonatomic, copy) NSString *name;
/** age */
@property (nonatomic, assign) NSInteger age;
@end
@implementation PeopleModel
- (instancetype)retain{
return [super retain];
}
- (oneway void)release{
[super release];
}
- (void)dealloc{
[super dealloc];
NSLog(@"%s\n",__func__);
}
*修正后文件
- (void)dealloc{
[super dealloc];
[_arrayMTest release];//释放数组
_arrayMTest = nil;
NSLog(@"%s",__func__);
}
image.png
解释:多次重复创建SubViewController ,然后diss释放,发现内存只增不减,原因数组中的对象没有手动释放,内存泄漏,对数组调用realse 会对其中的对象都调用release方法,同样的removeAllObjects 方法会对数组中的所有对象调用release 操作.
敲黑板:
- addObject 会调用对象的 retain方法
- removeAllObjects 会调用对象的release 方法
- 数组的release 会对其中的所有对象调用release 方法
总结: addObject 操作永远和remove 操作应该最好对等出现,否则就可能内存泄漏,及时释放数组
- 改造了下,方便对内存管理理解,代码如下:已测试没问题
@interface SubViewController ()
@property (nonatomic, strong)NSMutableArray * arrayMTest;
@property (nonatomic, strong)NSMutableArray * array0Test2;
@property (nonatomic, strong)NSMutableArray * array0Test3;
@property (nonatomic, copy)NSArray * array0Test4;
@end
@implementation SubViewController
- (void)dealloc{
[_arrayMTest release];
_arrayMTest = nil;
[_array0Test2 release];
_array0Test2 = nil;
[_array0Test3 release];
_array0Test3 = nil;
/*_array0Test4 不管是否手动释放,都不会内存泄漏,请思考为什么,下面会给出解释;建议还是手动释放,从内存管理语法层面还是写上去比较好;才采用静态分析的时候会给出错误的提示*/
// [_array0Test4 release];
// _array0Test4 = nil;
NSLog(@"%s",__func__);
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//release test
NSMutableArray * tempArray = [NSMutableArray new];
self.array0Test2 = tempArray;
self.array0Test3 = tempArray;
self.array0Test4 = tempArray;
NSLog(@"%ld",_array0Test2.retainCount);
self.arrayMTest = tempArray;
NSLog(@"%ld",_arrayMTest.retainCount);
for (NSInteger i = 0; i<10000;i++ ) {
PeopleModel * people1 = [[PeopleModel alloc] init];
people1.name = @"zhang";
people1.age = 1;
[_arrayMTest addObject:people1];
[people1 release];
}
[tempArray release];
}
下面分析为啥上面的不需要手动释放instrument也不会出现内存泄漏的问题
请仔细看代码self.array0Test4 = tempArray; 这里其实是copy 生成了一个指定空数组的指针,把带改造一下,在self.array0Test4 = tempArray;之前加一句NSArray * test = [NSArray new];会发现test 和array0Test4 指定的内存地址相容,引申一下所有的 [NSArray new]生成的内存都是同一块。这是系统优化的结果。打印array0Test4 的内存引用计数,结果输出为-1
网友评论