自從有了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]; }
然而事與願違仍是報錯了
事實證實不能夠對一個已經釋放的內存進行任何操做。