文章目录
ARC 规则
1. 不能使用retain/release/retainCount/autorelease
设置ARC有效时,禁止再次键入retain或release代码
在ARC无效时且手动进行内存管理时使用retain/release/retainCount/autorelease方法
2. 不能使用NSAllocateObject/NSDeallocateObject
3. 须遵守内存管理的方法命名规则
ARC无效时,用于对象生成/持有的方法必须遵守以下的命名规则
- alloc
- new
- copy
- mutableCopy
以上述名称开始的方法在返回对象时,必须返回给调用方所应当持有的对象,ARC有效时也一样
- init(ARC有效时)
以init开始的方法的规则要比alloc/new 更加严格该方法必须是实例方法必须要返回对象
init方法会初始化alloc方法返回的对象,然后原封不动的返还给调用方,该返回对象并不会注册到autorelease
4. 不要显式调用dealloc
对象所有者不持有该对象,该对象就被废弃,对象被废弃时,就会调用dealloc方法
ARC无效时直接调用[super dealloc], ARC有效时自动处理,无法显示调用
5. 使用@autoreleasepool块代替NSAutoreleasePool
ARC有效时,使用@autoreleasepool块代替NSAutoreleasepool,NSAutoreleasepool类不可使用时便会引起编译器报错。
6. 不能使用区域(NSZone)
ARC有效时,不能使用区域(NSZone)
7. 对象型变量不能作为C语言结构体的成员
ARC内存管理分配给编译器管理对象生存周期
要把对象型变量加入到结构体成员中时,可强制转换为void*或者附加unsafe__unreained修饰符
8. 显式转换id和void*
ARC无效时强制转换并不会出问题
在ARC有效时却会引起编译错误
单纯的赋值,可以使用__bridge(但是安全性很低)
另外两种 bridge__retained转换和__bridge_transfer转换
属性
ARC有效时,Object-C类的属性也会发生变化
ARC实现
在MRC中,内存管理主要有alloc/retain/release/dealloc
而在ARC中,我们是无法调用retain/release/dealloc这几个操作的,只有alloc是可以用的。我们可以理解为ARC帮助我们在适当的时候自动调用了这几个方法,对引用计数进行了管理
__strong修饰符
如果说在 MRC 时代 Retain 修饰符将会使被引用的对象引用计数 + 1 ,那么在 ARC 中 __strong 修饰符可以作为其替代者
- 自己生成并持有
id __strong obj0 = [[NSObject alloc] init];
NSLog(@"obj0 = %lu", CFGetRetainCount((__bridge CFTypeRef)obj0));
结果:
obj0 = 1
我们这里有两个东西,一个是obj0,它是一个指针,指向生成对象;同时,它使用了__strong,它也就持有了该对象,成为对象持有者,也就是说对象的引用计数+1了
2. 非自己生成并持有
id __strong obj = [NSMutableArray array];
此时会有一个优化的过程,看图就够了
__weak修饰符
若附有__weak修饰符的变量所引用的对象被废弃,则将nil赋值给该变量
使用附有__weak修饰符的变量,既是注册到autoreleasepool中的对象
然而关于weak进池的问题,据我测试和书上的代码不尽相同,
__weak修饰符的引用计数的问题
__autoreleasing修饰符
我们将对象赋值给附有__autoreleasing修饰符的变量等同于ARC无效时调用对象的autorelease方法