内存管理- MRC

来源:互联网 发布:新密传挂机软件 编辑:程序博客网 时间:2024/05/20 03:40
下列行为会增加一个app的内存应用
  • 创建一个OC对象
  • 定义一个变量
  • 调用一个函数或者方法

内存管理,涉及的操作:
  • 分配内存:如创建一个对象,会增加内存占用
  • 清除内存:如销毁一个对象,能减小内存占用

内存管理的管理范围
  • 任何继承了NSObject的对象
  • 对其它非对象类型无效(int, char, float, double, struct, enum等)

只有OC对象才需要进行内存管理的本质原因
  • Objective-C对象存放于堆里面
  • 非OC对象一般放在栈里面,而栈内存由系统自动管理

引用计数器:4字节
  • 每个OC对象都有自己的引用计数器
  • 是一个整数
  • 可理解为“对象被引用的次数”
  • 可理解为“有多少人正在用这个对象”
引用计数器常见操作
  • 当用alloc, new 或者 copy创建一个对象时,默认为1
  • 给对象发送一条retain消息,引用计数器值+1 (retain方法返回对象本身)
  • 给对象发送一条release消息,引用计数器值-1
  • 给对象发送一条retainCount消息,获得当前的引用计数器值
  • 注意:release并不代表对象被销毁,仅仅是计数器-1
dealloc
  • 当对象的引用计数器为0时,系统会自动给对象发送一条dealloc消息,对象被销毁,内存被回收
  • 一般会重写dealloc方法,在这里释放相关资源,最后要记得调用[super dealloc];
  • 不能自己手动调用dealloc方法

野指针 vs. 空指针
  • 僵尸对象:已经被销毁的对象
  • 野指针:指向僵尸对象(不可用内存)的指针;给野指针发消息会报EXC_BAD_ACCESS错误
  • 空指针:指向nil,给nil发消息没有任何反应,也不会崩溃
  • 避免指向野指针:在对象被销毁后,将指向对象的指针变为空指针。

内存管理原则:
  • 谁创建谁release
  • 谁retain谁release
  • 总结:有加就有减

set方法的内存管理
-(void) setSomething:(Something *) something {
     if (something != _something) {
          [_something release];  
          _something = [something retain];
     }
}

dealloc方法的内存管理
-(void) dealloc {
     [_something release];
     [super dealloc];
}

@property参数
控制set方法的内存管理
  • retain: release 旧值,retain新值 (用于OC对象)
  • assign: 直接赋值,不做任何内存管理(默认,用于非OC对象)
  • copy: release旧值,copy新值(一般用于NSString *)
控制需不要生成set方法
  • readwrite: 同时生成set方法和get方法(默认
  • readonly: 只会生成get方法
多线程管理
  • atomic: 性能低(默认
  • nonatomic:性能高

循环retain
  • A对象retain了B对象,B对象retain了A对象
  • 弊端:导致A, B对象永远无法释放
  • 解决方案:当两端相互引用时,一端用retain, 一端用assign

autorelease基本作用
  • 给对象发送一条autorelease消息,会将对象放到一个自动释放池中
  • 当自动释放池被销毁时,会对池子里的所有对象做一次release操作
  • 会返回对象本身
  • 调用完autorelease方法后,对象的计数器不变
autorelease的好处
  • 不用再关心对象的释放时间
  • 不用再关心什么时候调用release
autorelease的使用注意
  • 占用内存较大的对象不要随便使用autorelease
  • 占用内存较小的对象使用autorelease,没有太大影响
  • 一般可以为类添加一个快速创建对象的类方法
    • + (instancetype) object { return [[[self alloc] init] autorelese]; }
  • 一般来说,除了alloc, new, 或copy 之外的方法创建的对象都被声明了autorelease


自动释放池autoreleasepool{ }
  • 自动释放池以栈结构存在(先进后出)
  • 当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池
  • 自动释放池的创建方式:autoreleasepool{ }
1 0
原创粉丝点击