Objective-C 内存管理

Objective-C内存管理使用的技术是引用计数(Reference Counting)。从开始的MRC(Manual),到后来的ARC(Automatic)。

使用ARC的好处:

1)程序员无需再写retain和release代码,很大程度上减少了开发工作量。

2)系统比程序员清楚对象什么时候该被销毁,降低了crash和leak的风险。

关于引用计数,《Objective-C 高级编程》的“开关房间的灯”例子讲得很形象,其中的对应关系如下:

1)灯,是对象。

2)人,是引用对象的变量。其实就是对象的地址,这里需要理解指针和指针指向的内容。

3)开灯:生成对象。

4)需要照明:持有对象。

5)不需要照明:释放对象。这里的释放特指release。

6)关灯:销毁对象。

上面提到引用计数机制中最核心的四种对象操作,现在来看看它们对应的方法: 

1)生成对象:以alloc/new/copy/mutableCopy开头的方法

// 生成并持有一个堆中的NSObject对象,obj是对象的指针,对象的引用计数+1
id obj = [[NSObject alloc] init];
id obj = [NSObject new];

实践证明,copy和mutableCopy方法并不一定会生成对象,具体见: 

https://www.cnblogs.com/yangwenhuan/p/9572774.html

2)持有对象:retain

3)释放对象:release

4)销毁对象:dealloc

  

NSAutoreleasePool重写了NSObject中的autorelease方法,一旦调用,就会crash:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool autorelease]; // crash

ARC和MRC的本质一样,只是ARC自动帮程序员做了些事情。在一个app中,两者可以混用,最小单位是文件。

工程配置文件 -> 特定target -> Build Phases -> Compile Sources -> 特定文件: 

-fobjc-arc // 使用ARC,Xcode4.2及以上版本的默认值
-fno-objc-arc // 不使用ARC

ARC中有四种对象所有权修饰符:

1)__strong

变量强引用对象,默认值

// 两种写法等价
NSObject *obj = [[NSObject alloc] init];
NSObject * __strong obj = [[NSObject alloc] init];

__strong变量超出作用域时,会释放它引用的对象 

2)__weak

3)__unsafe_unretained

不安全,不持有对象。如果对象被销毁,__unsafe_unretained变量会变成野指针,继续访问会导致crash,所以使用前一定要保证对象存在。

NSObject * __unsafe_unretained obj = [[NSObject alloc] init];
// NSObject对象在init完,引用计数就为0,被销毁,再访问obj变量会导致crash

4)__autoreleasing

获取对象的引用计数,但其实这个函数在有些情况下并不靠谱,所以个人建议最好不用。

uintptr_t _objc_rootRetainCount(id obj)
原文地址:https://www.cnblogs.com/yangwenhuan/p/8467535.html