记重读《Objective-C高级编程》- ARC
一、ARC
无需再次(禁止)键入retain或者是release代码
1.__strong
(1) 以alloc/new/copy/mutableCopy/init 开头的方法,单纯的插入release
{
id __strong obj = [[NSObject alloc] init];
}
相当于:
{
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj, @selector(init));
objc_release(obj);
}
(2) objc_autoreleaseReturnValue() 和 objc_retainAutoreleaseReturnValue()配合来提升效率,不被注册到AutoreleasePool。按常理讲,id obj = [NSMutableArray array];
obj指向的对象应该注册到AutoreleasePool中,但是ARC做了优化,前面两个函数加在一起配合时,就不会被注册到AutoreleasePool,直接使用。
外部使用:
{
id __strong obj = [NSMutableArray array];
}
ARC下等同于:
{
id obj = objc_msgSend(NSMutableArray, @selector(array));
objc_retainAutoreleaseReturnValue(obj); // 在外面使用了retainAuto
objc_release(obj);
}
NSMutableArray内部:
+ (id) array
{
return [[NSMutableArray alloc] init];
}
ARC下等同于:
+ (id) array
{
id obj = objc_msgSend(NSMutableArray, @selector(alloc));
objc_msgSend(obj, @selector(init));
return objc_autoreleaseReturnValue(obj); // 内部使用auto
}
2.__weak
附有__weak修饰符的变量必定会访问AutoreleasePool中的对象:
(1)引用:因为__weak只持有对象的弱引用,而在访问引用对象的过程中,该对象有可能被废弃。如果把要访问的对象注册到AutoreleasePool中,那么在@autoreleasepool块结束之前都能确保该对象存在。
(2)理解:__weak wkObj = obj;
只有当wkObj被使用的时候,obj才会被注册到AutoreleasePool中,引用计数也会增加。
3.__autoreleasing
将对象赋值给附有__autoreleasing修饰符的变量,等同于MRC下调用对象的autorelease方法。ARC借助AutoreleasePool的能力来处理。
二、Autorelease:
自动变量的作用域,超出作用域后自动调用release。
-
调用autorelease方法的变量会在 AutoreleasePool 作用域结束时被自动调用release
-
AutoreleasePool 会持有对象
-
自己生成并持有的对象(自己:对象的使用环境/编程人员自己):alloc/new/copy/mutableCopy 或以此开头
-
“非自己生成并持有”的对象,即不是以 alloc/new/copy/mutableCopy 开头的方法获得的对象,对象会被注册到AutoreleasePool中
-
init方法返回的对象,不会被注册到AutoreleasePool中
-
不使用 __autoreleasing 修饰符时,如果对象是函数返回值,那么对象也会被编译器注册AutoreleasePool中
-
id *obj
==id __autoreleasing *obj;
NSError **obj
==NSError * __autoreleasing *obj;
OC中的自动变量
- 局部变量
- 函数
- 方法参数