自从有了ARC不少朋友都忽略了MRC的重要性,ARC并非万能的,在你使用C底层框架的时候仍是须要理解MRC的,至少须要知道简单的使用。框架
先说说MRC下的几个属性定义的关键字:atom
retain:相似ARC下的strong引用计数+1.code
assign:用于基本数据相似赋值,非oc对象,不对引用计数操做。对象
copy:用于相似NSString这类的。继承
这里建立了一个testModel来进行讲解。
内存
retain引用计数+1,release引用计数-1.it
TestModel.h
内存管理
@property(nonatomic,copy)NSString * myName;
TestModel.mio
复写Delloc,由于是继承与NSObject全部还要调用一下父类的dealloc。class
- (void)dealloc { NSLog(@"Model1被释放了"); [super dealloc]; }
ViewController.m
@interface ViewController () { TestModel * _testModel1; } - (void)viewDidLoad { [super viewDidLoad]; _testModel1 = [[TestModel alloc]init]; [_testModel1 retain]; NSLog(@"1引用计数为%lu",(unsigned long)[_testModel1 retainCount]); [_testModel1 release]; NSLog(@"2引用计数%lu",[_testModel1 retainCount]); _testModel1.myName = @"Bob"; NSLog(@"name:%@",_testModel1.myName); NSLog(@"3引用计数%lu",[_testModel1 retainCount]); [_testModel1 release]; } //打印结果 1引用计数为2 2引用计数1 name:Bob 3引用计数1 Model1被释放了 //这样应该就很简单的看懂了retain和release的用法了
Xcode还有一个功能能够检查内存管理的问题,也就是zombie。
Product-->Scheme-->Edit Scheme-->勾选Enable Zombie Objects.
这个时候咱们能够验证一下
#import "ViewController.h" #import "TestModel.h" @interface ViewController () { TestModel * _testModel1; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _testModel1 = [[TestModel alloc]init]; [_testModel1 retain]; NSLog(@"1引用计数为%lu",(unsigned long)[_testModel1 retainCount]); [_testModel1 release]; NSLog(@"2引用计数%lu",[_testModel1 retainCount]); _testModel1.myName = @"Bob"; NSLog(@"name:%@",_testModel1.myName); NSLog(@"3引用计数%lu",[_testModel1 retainCount]); [_testModel1 release]; _testModel1.myName = @"Mary"; }
看以上代码,能够看出_testModel1的引用计数已经为0了,而我却还对他的属性赋值,只是在对一个僵尸内存进行操做会报错。
那有盆友就会想那我在给retain不就复活了?然而要明白人死不能复生,你再怎么给他引用计数+1都没用,由于系统会自动将引用计数为0的内存释放了,因此他已经不存在了。
那就有盆友想象,那为了保证个人引用计数最后是为0,那就多release几回的,干净点,那就来试试吧。
#import "ViewController.h" #import "TestModel.h" @interface ViewController () { TestModel * _testModel1; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _testModel1 = [[TestModel alloc]init]; [_testModel1 retain]; NSLog(@"1引用计数为%lu",(unsigned long)[_testModel1 retainCount]); [_testModel1 release]; NSLog(@"2引用计数%lu",[_testModel1 retainCount]); _testModel1.myName = @"Bob"; NSLog(@"name:%@",_testModel1.myName); NSLog(@"3引用计数%lu",[_testModel1 retainCount]); [_testModel1 release]; [_testModel1 release]; }
然而事与愿违仍是报错了
事实证实不能够对一个已经释放的内存进行任何操做。