iOS随笔-生活工作点滴

记重读《Objective-C高级编程》- ARC

2019-07-08  本文已影响0人  ChinaChong

一、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。

  1. 调用autorelease方法的变量会在 AutoreleasePool 作用域结束时被自动调用release

  2. AutoreleasePool 会持有对象

  3. 自己生成并持有的对象(自己:对象的使用环境/编程人员自己):alloc/new/copy/mutableCopy 或以此开头

  4. “非自己生成并持有”的对象,即不是以 alloc/new/copy/mutableCopy 开头的方法获得的对象,对象会被注册到AutoreleasePool中

  5. init方法返回的对象,不会被注册到AutoreleasePool中

  6. 不使用 __autoreleasing 修饰符时,如果对象是函数返回值,那么对象也会被编译器注册AutoreleasePool中

  7. id *obj == id __autoreleasing *obj; NSError **obj == NSError * __autoreleasing *obj;

OC中的自动变量

  1. 局部变量
  2. 函数
  3. 方法参数
上一篇下一篇

猜你喜欢

热点阅读