OC - OC的内存管理机制

2016-06-16  本文已影响284人  千山小畻

导读

一、 为什么要进行内存管理

  1. 移动设备分配给每个App的内存有限,App运行中会创建大量对象, OC对象存储在堆中,系统不会自动释放堆中的内存,对象没有及时释放,就会占用大量内存,系统会发出内存警告,对应用运行造成影响。

二、内存管理机制

  1. 在C#中都有GC在自动管理内存,但是在OC中没有垃圾回收机制,OC提供了一套机制来管理内存,即“引用计数”(retain counting):
内存管理范围:任何继承NSObject的对象;OC中的基本类型存储在栈上,由系统进行管理。 
内存管理方法有:MRC(手动引用计数)、ARC(自动引用计数)、Autorelease(自动释放池)。

三、内存管理原则

  1. 谁创建, 谁release。
    如果你通过alloc、new、copy来创建了一个对象,那么你就必须调用release或者autorelease方法。不是你创建的就不用你去负责。
  2. 谁retain, 谁release。
    只要你调用了retain,无论这个对象时如何生成的,你都要调用release。
  3. 除了alloc、new或copy之外的方法创建的对象在内部都被声明了autorelease,如[UIButton buttonWithType:]
  4. 在一定的代码段内,对同一个对象所做的copy、alloc和retain的操作次数应当与release和 autorelease操作的次数相等。
    Apple官网内存管理三定律
    1. 一个对象可以有一个或多个拥有者
    2. 当对象一个拥有者都没有时,就会被回收
    3. 一个对象如果想保留不被回收,必须具有拥有者

四、MRC手动引用计数

(一) Set方法的代码规范
  1. 基本数据类型:直接复制
    -(void)setAge:(int)age
    {
    _age=age;
    }
  2. OC对象类型
    -(void)setCar:(Car *)car
    {
    //先判断是不是新传进来的对象
    If(car!=_car)
    {
    //对旧对象做一次release
    [_car release];//若没有旧对象,则没有影响
    //对新对象做一次retain
    _car=[car retain];
    }
    }
(二) dealloc方法的代码规范
  1. 一定要[super dealloc],而且要放到最后
  2. 对self(当前)所拥有的的其他对象做一次release操作
    -(void)dealloc
    {
    [_car release];
    [super dealloc];
    }
(三) 实例代码规范
  1. WZKPerson.h
#import <Foundation/Foundation.h>
@interface WZKPerson : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSInteger age;
@end

五、ARC内存管理机制

(一) ARC的判断准则
(二) 指针分类
  1. 声明一个弱指针如下:
    _ _weak Person *p;
    //ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空操作。
    _ _weak Person *p=[[Person alloc] init];
    //不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针自动清零。
  2. ARC中在property处不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc]
    @property(nonatomic,strong)Dog *dog;
    // 意味着生成的成员变量dog是一个强指针,相当于以前的retain。
    //如果换成是弱指针,则换成weak,不需要加
    _。
(三) ARC的特点总结
  1. 不允许调用release、retain、retainCount
 Strong:相当于原来的retain(适用于OC对象类型),成员变量是强指针
Weak:相当于原来的assign(适用于oc对象类型),成员变量是弱指针
Assign:适用于非OC对象类型(基础类型)
(四) 补充
  1. 让程序兼容ARC和非ARC部分。转变为非ARC -fno-objc-arc 转变为ARC的, -f-objc-arc 。

六、 Autorelease自动释放池

(一) 下面通过代码来了解一下自动释放池
  1. WZKPerson.h
    //构造函数
    -(WZKPerson *)initWithName:(NSString *)name age:(NSInteger)age;
    //获取对象的类方法
    +(WZKPerson *)personWithName:(NSString *)name;
(二) 自动内存释放总结
1. 基本用法
2. 好处
3. 使用注意
4. 错误写法
上一篇 下一篇

猜你喜欢

热点阅读