iOS 所有权修饰符 __strong, __weak, __unsafe_unretained, __autoreleasing
这些修饰符,只有在 ARC 打开的时候才会用到
内存管理规则:
1. 自己生成的对象,自己所持有
2. 非自己生成的对象,自己也能持有
3. 不再需要自己持有的对象时释放
4. 非自己持有的对象无法释放
__strong 强引用,持有对象
- 默认加在所有对象类型前
NSObject *obj = [[NSObject alloc] init];
// 相当于下面这句
NSObject * __strong obj = [[NSObject alloc] init];
- 当超出变量作用域后,自动释放对象
- 修饰方法参
- 修饰成员变量
__strong 会造成强引用。需要用 __weak 来避免强引用
__weak 弱引用,不持有对象
- __weak 对象引用
// obj0 生成之后会立马释放,因为 __weak 不强引用,当对象没有被强引用时,会自动销毁
NSObject * __weak obj0 = [[NSObject alloc] init];
// 下面的代码 obj2 弱引用了 对象,当 obj1 释放时, obj2 也会释放
NSObject *obj1 = [[NSObject alloc] init];
NSObject * __weak obj2 = obj1;
- 自动置 nil, 当 __weak 修饰的变量释放时,会自动赋值为 nil
__unsafe_unretained 修饰符
- 与 __weak 一样不持有对象
- 不会对已经释放的 变量 置 nil,有可能访问不存在的内存
- 使用 __unsafe_unretained 时,必须确认它修饰的变量确实存在。
用 __weak 代替 __unsafe_unretained
__autoreleasing
ARC 中也可以使用 autoreleasing
ARC 中使用 @autoreleasepool
非 ARC 中使用 NSAutoreleasePool
非显性使用 __autoreleasing
- 当持有非自己生成的对象时,自动将返回对象注册到 autoreleasepool 中
- 使用 __weak 修饰的变量,会自动 注册到 autoreleasepool 中
- 双指针变量(包括在做方法参数时) 自动注册到 autoreleasepool 中, NSObject **obj 即 NSObject * __autoreleasing *obj
__strong 和 __autoreleasing 在方法参数上的区别
- __strong 修饰单指针
- __autoreleasing 修饰双指针
_objc_autoreleasePoolPrint(); 可以 查看调试 注册到 autoreleasing 中的对象
ARC 规则:
1. 不能使用 retain/release/retainCount/autorelease
2. 不能使用 NSAllocateObject/NSDeallocateObject
3. 必须遵守内存管理的方法命名规则
4. 不要显式调用 dealloc
5. 使用 @autoreleasepool 块,替换 NSAutoreleasePool
6. 不能使用区域 NSZone
7. 对象类型不能作为 C 语言结构体(stuct/union) 的成员
8. * 显式转款 "id" 和 “void *”