內存管理一

自從有了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];
    
}

然而事與願違仍是報錯了

事實證實不能夠對一個已經釋放的內存進行任何操做。

相關文章
相關標籤/搜索