内存管理一

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

然而事与愿违仍是报错了

事实证实不能够对一个已经释放的内存进行任何操做。

相关文章
相关标签/搜索