Objective-C中的内存管理是采用引用计数实现的,所谓引用计数(ARC,Automatic Reference Counting)是指内存管理中对引用采取自动计数的技术,当需要强引用对象时对象计数+1,不强引用时对象计数-1,当对象的引用数为0时即销毁。
内存管理的思考方式
Objective-C中内存管理遵循以下原则
- 自己生成的对象,自己持有。
- 非自己生成的对象,自己也能持有。
- 不再需要自己持有的对象时释放。
- 非自己持有的对象无法释放。 上面出现的“生成”、“持有”、“释放”再加上“废弃”这4个动作对应的Objective-C中方法如下表所示:
| 对象操作 | Objective-C方法 |
|---|---|
| 生成并持有对象 | alloc/new/copy/mutableCopy等方法 |
| 持有对象 | retain方法 |
| 释放对象 | release方法 |
| 废弃对象 | dealloc方法 |
所有权修饰符
Objective-C中所有权修饰符一共有4种,分别为:
- __strong修饰符
- __weak修饰符
- __unsafe_unretained修饰符
- __autoreleasing修饰符
__strong修饰符
__strong修饰符是id类型和对象类型默认的所有权修饰符,表示持有对象。
__weak修饰符
weak修饰符与strong修饰符相反,提供弱引用,不持有对象,当指向的对象废气时自动变成nil,正因如此它能完美解决循环引用问题。
__unsafe_unretained修饰符
__unsafe_unretained修饰符正如其名unsafe所示,是不安全的所有权修饰符,用它修饰的变量也不能持有对象,但是当所指向的对象废气时其值不会变成nil,这种情景下就会产生野指针,故而不安全。
__autoreleasing修饰符
autoreleasing修饰符表示该对象已注册到autoreleasepool中,该修饰符一般用于id的对象或者对象的指针,在CocoaTouch框架中一般返回error值时通常会用(NSError* autoreleasing)error方式,这里之所以选用__autoreleasing修饰符是为了符合*内存管理思考方式:
作为alloc/new/copy/mutableCopy方法返回值取得的对象是自己生成并持有的,其它情况下便是取得非自己生成并持有的对象。因此,使用附有__autoreleasing修饰符的变量作为对象取得参数,与除alloc/new/copy/mutable/Copy外其他方法的返回值取得对象完全一样,都会注册到autoreleasepool,并取得非自己生成并持有的对象。
属性与所有权修饰符
属性声明的属性与所有权修饰符的对应关系如下表所示:
| 属性声明的属性 | 所有权修饰符 |
|---|---|
| assign | __unsafe_unretained修饰符 |
| copy | __strong修饰符(但是赋值的是被复制的对象) |
| retain | __strong修饰符 |
| strong | __strong修饰符 |
| unsafe_unretained | __unsafe_unretained修饰符 |
| weak | __weak修饰符 |
以上各种属性赋值给指定的属性中就相当于赋值给附加各属性对应的所有权修饰符的变量中。只有copy属性不是简单的赋值,它赋值的是通过NSCopying接口的copyWithZone:方法复制赋值源所生成的对象。