oc内存管理

来源:互联网 发布:数据比对 编辑:程序博客网 时间:2024/06/07 05:55

一.OC内存管理机制


1.内存管理

OC内存管理的范围是所有继承自NSObbject的对象。对基本数据类型是无效的。(基本数据类型的对象由系统自动回收)

OC内存管理是是使用引用计数法则,当一个对象被创建时便会有retainCount(引用计数器)这个属性。

2.引用计数器

每个OC对象都有一个8位的引用计数器,当使用alloc,new或者copy的来创建一个新对象的时候,新对象的引用计数默认被设置为1

当一个对象的引用计数为0时,这个对象便会被系统回收

对象的引用计数不为0时,在程序运行中,它所占用的内存时不会被回收的,直到程序运行结束。

3.引用计数的操作

给对象发送retain消息时,引用计数加1

给对象发送release消息时,引用计数减1

给对象发送retainCount消息时,可以获得当前的引用计数值

4.对象销毁

当一个对象的引用计数为 0时,它所占用的内存便会被系统回收。对象销毁一般调用的是dealloc方法。

野指针

这里需要注意的是避免野指针的出现,当对象被回收那么他对应的内存便不能再使用,强行使用的话会导致程序崩溃。

而野指针指的就是那些指向僵尸对象(不可用内存)的指针。

为了避免野指针的出现一般在对象被回收之后,将指设置为空指针。

如:

    Person *p = [[Person alloc] init];    [p release];    //当实例对象被释放后,不能给它发送任何一条消息。    p = nil;


二.内存管理方式

1.内存管理的原则

内存管理的黄金法则,如果一个对一个对象使用了alloc,copy,retain,那么必须使用的相应的relese或者autorelease进行释放。(即谁创建谁释放)

2.set方法管理内存

如果一个类中有一个OC对象的成员变量,则这个类必须负责这个成员变量相关的内存。

例如一个人拥有一辆车,那么在人的对象被销毁之前必须先将车的引用计数器减一。


- (void)setCar:(Car *)car {    //判断是否自我赋值    if (_car != car)    {//对正在使用的车做一次release        [_car release];        _car = [car retain];    }}- (void)dealloc {    NSLog(@“Person被释放");//在人被销毁之前,先对车做一次release    [_car release];    [super dealloc];}


3.@property参数

@property可以自动生成setter方法和getter方法的声明和实现,除此之外@property还可以加入一些参数来对自动生成的setter方法和getter进行限定。

比如: @property(retain,readonly) int a;


三.循环引用

循环引用指的是两个对象相互retain,导致两个永远无法释放。

B.h中

@property (nonatomic,retain) A;

A.h中

@property (nonatomic,retain) B;

这样就会造成循环引用。

解决方案,一端用assign,另一端用retain


四.autorelease方法

给对象发送一条autorelease消息之后,对象被放入到一个自动释放池中

当自动释放池销毁时,会给释放池中调用过autorelease的对象发送一条release消息

autorelease只是延迟了对release的调用,并不会改变对象本身的计数器。

自动释放池的创建

    @autoreleasepool {

在此加入对象

           }


五.ARC

ARC是自动管理内存的,在ARC中有强指针和弱指针分别用(_strong和_weak修饰),当没有强指针指向对象时,就会释放改对象。

循环引用,在ARC中也存在循环引用,

如:

在B.h中

@property (nonatomic,strong) A;

在A.h中

@property (nonatomic,strong) B;

解决方式是一个用weak修饰,一个用strong修饰


一个项目中可以兼容MRC和ARC。

0 0
原创粉丝点击