type
status
date
slug
summary
tags
category
icon
password
本篇主要讲述如何在开发中自如的切换MRC与ARC,虽然MRC项目以及很少存在,但是了解其本质,也就是ARC。
本文有一点需要注意,在涉及到autorelease部分,将会统一放在内存管理(六)autorelease中讲述。

一、MRC

1.1 方法

MRC内存管理,在调用相关内存方法如下表:
notion image

1.2 内存管理原则

那么如何使用调用上面这些方法呢?需要根据内存的管理原则,有如下4条:
notion image
  • 自己生成的对象,自己持有
  • 非自己生成的对象,自己也能持有
  • 不再需要自己持有的对象时释放
  • 非自己持有的对象无法释放
其中非自己生成的对象,且该对象存在,但自己不持有 这个特性是使用autorelease来实现的,示例代码如下:
autorelease 使得对象在超出生命周期后能正确的被释放(通过调用release方法)。在调用 release 后,对象会被立即释放,而调用 autorelease 后,对象不会被立即释放,而是注册到 autoreleasepool 中,经过一段时间后 pool结束,此时调用release方法,对象被释放。这部分内容将会在内存管理(六)autorelease详述。

1.3 setter方法

在了解了如何调用方法之后,我们仍然需要对@property做一定的了解,虽然MRC下,Xcode也会为我们自动生成setter。现在看下它们是如何实现的。

1.3.1 内存管理语义的属性特质

在MRC下,有如下几个:
notion image

1.3.2 实现

先给出一个示例类,示例代码见-MRC-引用计数
  • assign针对纯量类型,使用assign,并且因为没有涉及到引用计数,其setter为简单的赋值操作。
  • retain针对对象类型,就需要管理对象的引用计数,retain的含义及时要表明拥有权,即强引用。此时需要对传递进来的对象进行retain,增加引用计数,代表有新指针强引用它。至于在retain之前,为什么要进行release,可以看示例代码一探究竟。
  • copy的操作和retain非常相似。但是对象进行copy,至于copy后是创建新对象,还是在传递进来的原有对象上进行引用计数加1,就需要视情况而定,这部分在后面内存管理(五)copy有更详细的讲述。
  • unsafe_unretainedassign类似,但是可以用在对象类型上,它不会影响传递进来的对象引用计数,只是进行简单的赋值。

1.4 应用

忘记release,可能导致内存泄漏。
下面是一个更为复杂的使用:

二、ARC

ARC,Automatic Reference Count ,自动引用计数,是MRC的体面版,OC开发者不再像C开发者那样,对指针怨念幽深了,对引用计数的操作由ARC自动管理。
ARC帮我们做了一些工作,主要分为两部分:
  • 编译期:在编译时,编译器会分析源码中每个对象的生命周期,然后基于这些对象的生命周期,来添加相应的引用计数操作代码。
  • RuntimeRunLoop:这两者会协同工作,以保证弱引用以及自动释放池的工作顺利进行,并对程序进行一定的优化。

2.1 __strong

notion image

2.2 __weak

notion image

2.3 __unsafe_unretained

notion image

2.4 @perperty

属性的本质其实仍然没有改变,因为内存管理的根基——引用计数没有变。

三、Core Foundation

就算用上了ARC,无处不在的ARC,但是仍然由鞭长莫及的地方——Core Foundation。
Core Foundation框架中的CF对象,以及我们常用的Foundation中的NS对象,由Toll-free bridging技术进行转换。
notion image
下面是进行转换的示例,代码在--ARC

四、混编

Xcode支持MRC与ARC混编,只要在对应的源文件指定即可,指定的关键字分别是:-fno-objc-arc-fobjc-arc

4.1 MRC中开启ARC

notion image

4.2 ARC中开启MRC

notion image

参考

链接
  1. Automatic Reference Counting
  1. Memory Management Programming Guide for Core Foundation
  1. Transitioning to ARC Release Notes
 
示例代码
  1. MRC-引用计数
  1. ARC