Objective-C的内存管理

时间:2021-12-04 02:11:28

一、Objective-C内存管理的对象

1. 值类型:比如int、float、struct等基本数据类型。

  • 值类型会被放入栈中,在内存中占有一块连续的内存空间,遵循先进后出的原则,故不会产生碎片。
  • 由系统分配管理

2. 引用类型:Objective-C的对象

  • 引用类型会被放到堆中,内存分配按照一定的分配算法,但无论算法多优,总会产生碎片。
  • 内存的分配和释放由程序员操作管理

3. 值类型和引用类型之间的相互转化

  • 装箱:把值类型转化为引用类型的过程叫做装箱,如把int包装为NSNumber。
  • 拆箱:把引用类型转为值类型的过程叫做拆箱,如把NSNumer转为int。

二、Objective-C内存管理的对象的方法

1. 引用计数

  • 表示对象被引用的次数,通过它可以判断对象是否被回收。
  • 如果引用计数为0,对象回收,不为0则不回收。
  • 当对象执行alloc、new、copy或者retain时,引用计数加1,release时,引用计数减1。

三、Objective-C管理内存的方式

1. 手动内存管理机制:MRC

  • MRC模式下,所有的对象都需要手动的添加retain、release代码来管理内存。
  • 使用MRC,需要遵守谁创建,谁回收的原则。也就是谁alloc,谁release;谁retain,谁release。
  • 当引用计数为0的时候,必须回收,引用计数不为0,不能回收,如果引用计数为0,但是没有回收,会造成内存泄露。如果引用计数为0,继续释放,会造成野指针。为了避免出现野指针,我们在释放的时候,会先让指针置为nil。

2. 自动内存管理机制:ARC

1)ARC模式下的property变量修饰词

  • 强引用strong:相当于retain,使用之后,计数器值+1。
  • 弱引用weak:相当于assign,使用不会改变计数器的值,指针指向的地址被释放后,会自动置为nil。
  • retain:引用计数值+1,即对象持有者的个数+1。
  • assign:设置变量时使用,不设计引用计数。
  • copy:拷贝对象。
  • readwrite与readonly:限制访问者的权限。
  • atomic与nonatomic:原子操作与非原子操作。原子操作适用于多线程,对共享资源的安全访问。非原子操作多用于非多线程,可以提高性能。

2)自动释放池

自动内存释放使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelase方法,那么当代码块执行完之后,在块中调用过autorelease方法的对象都会自动调用一次release方法。这样一来就起到了自动释放的作用,同时对象的销毁过程也得到了延迟(统一调用release方法)。

  1. autorelease方法不会改变对象的引用计数器,只是将这个对象放到自动释放池中;
  2. 自动释放池实质是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如如果一个对象的引用计数器>1则此时就无法销毁);
  3. 由于自动释放池最后统一销毁对象,因此如果一个操作比较占用内存(对象比较多或者对象占用资源比较多),最好不要放到自动释放池或者考虑放到多个自动释放池;
  4. ObjC中类库中的静态方法一般都不需要手动释放,内部已经调用了autorelease方法;