ARC规则

title: ARC规则
date: 2016-03-17 16:49:05
categories: iOS
tags: Objective-C高级编程 iOS与OS X多线程和内存管理


作者:秋儿(lvruifei@foxmail.com

学习笔记 二 之《Objective-C高级编程 iOS与OS X多线程和内存管理》

第一章:自动引用计数

ARC 规则

ARC 所有权修饰符:

  • __strong:

    对对象强引用,变量超出其作用域时被废弃,强引用失效,对象也随之释放(id 类型和对象类型默认为 __strong 修饰符)

  • __weak:

在持有某对象的弱引用时,若对象被废弃,则此弱引用将自动失效且处于nil 被赋值的状态(空弱引用)。只能用于 iOS5 和 OS X Lion 以上版本,以下可使用 __unsafe_unretained 修饰符来代替。 
  • __unsafe_unretained:

    被修饰的变量不属于编译器的内存管理对象,是 __weak 的代替

  • __autoreleasing:

    @autoreleasepool 块代替 NSAutoreleasePool 类对象生成,持有,废弃这一范围

    __autoreleasing 修饰符 等价于在 ARC 无效时调用对象的 autorelease 方法

    编译器会检查方法名是否是以 alloc/new/copy/mutableCopy 开始,不是,则自动将返回值得对象注册到 autoreleasepool

    访问 __weak 修饰符的变量时必须访问注册到 autoreleasepool 的对象

    id 的指针或对象的指针会默认附加上 __autoreleasing 修饰符

    赋值给对象指针时,所有权修饰符必须一致:

      NSError *error = nil;
      NSError * __strong *pError = &error;
      
      NSError _weak *error = nil;
      NSError * __weak *pError = &error;
    

    NSRunLoop 等实现不论 ARC 有效还是无效,均能够随时释放注册到 autoreleasepool 中的对象。

    ARC 无效时 @autoreleasepool 块 _objc_autoreleasePoolPrint() 均能使用。

ARC 规则:

  • 不能使用 retain/release/retainCount/autorelease:

    内存管理是编译器的工作

  • 不能使用 NSAllocateObject/NSDeallocateObject

  • 需遵守内存管理的方法命名规则:

    init 开始的方法返回的对象并不注册到autoreleasepool 上

    init 方法返回的对象应为 id 类型或该方法声明类的对象类型,或者是该类的超类型或子类型

  • 不要显式调用 dealloc

  • 使用 @autoreleasepool 块替代 NSAutoreleasePool

  • 不能使用区域(NSZone):

    不管 ARC 是否有效,区域在现在的运行时系统中已单纯的被忽略

  • 对象型变量不能作为 C 语言结构体(struct/union)的成员:

    要把对象型变量加入到结构体成员中时,可强制转换为 void * 或者是附加 __unsafe_unretained 修饰符

      struct Data {
          NSMutableArray __unsafe_unretained *array;
      };
    
  • 显式转换 "id" 和 "void *"

    在 ARC 无效时,将 void * 变量赋值给 id 变量,调用其实例方法,运行时不会有问题

      //ARC 无效
      id obj = [[NSObject alloc] init];
      void *p = obj;
      id o = p;
      [o release];
    

    在 ARC 有效时,上面的代码会引起编译错误。id 型或对象型变量赋值给 void * 或者逆向赋值时都需要进行特定的转换。如果只想单纯地赋值,则可以使用 “__bridge 转换”

      id obj = [[NSObject alloc] init];
      void *p = (__bridge void *)obj;
      id o = (__bridge id)p;
    

    转换为 void * 的 __bridge 转换,其安全性与赋值给 __unsafe_unretained 修饰符相近,甚至更低。如果管理时不注意赋值对象的所有者,就会因悬垂指针而导致程序崩溃。

    __bridge 转换中还有 “__bridge_retained 转换” 和 “__bridge_transfer转换”

    • __bridge_retained 使要转换赋值的变量也持有所赋值的对象, 与retain 相似
    • __bridge_transfer 与上面的相反,被转换的变量所持有的对象在该变量被赋值给转换目标变量后随之释放,与 release 相似
Objective-C 对象和 Core Foundation 对象,后者主要使用在用 C 语言编写的 Core Foundation 框架中,使用引用计数的对象。两者区别很小,不同之处只在于由哪一个框架所生成。一旦生成,便能在不同的框架中使用。


    CFMutableArrayRef cgObject = NULL;
    {
        id obj = [[NSMutableArray alloc] init];
        cfObject = CFBridgeRetain(obj);
        CFShow(cfObject);
        printf("retain count = %d\n",CFGetRetainCount(cfObject));// 2
    }
    printf("retain count after scope = %d\n",CFGetRetainCount(cfObject));// 1
    CFRelease(cfObject);

__bridge_retained 转换 可以代替 CFBridgeRetain,当然,__bridge_transfer 转换也可以替代 CFBridgeRelease

属性:

属性声明的属性 所有权修饰符
assin __unsafe_unretained 修饰符
copy __strong 修饰符(但是赋值的是被复制的对象)
retain __strong 修饰符
strong __strong 修饰符
unsafe_unretained __unsafe_unretained 修饰符
weak __weak 修饰符

声明类成员变量时,如果同属性声明中的属性不一致,则会引起编译错误,如:

// 错误
id obj;
@property (nonatomic, weak) id obj;


// 正确
id __weak obj;
@property (nonatomic, weak) id obj;

// 正确
id obj;
@property (nonatomic, strong) id obj;

数组:

数组超出其变量作用域时,数组中各个附有 __strong 修饰符的变量也随之失效,其强引用消失,对象随之释放。

  • calloc 函数分配内存会使分配区域初始化为0
  • malloc 函数分配内存后区域没有被初始化0,可用 memset 等函数将内存填充为 0

ARC 的实现:

ARC 是由编译器进行内存管理,但是需要 Objective-C 运行时库的协助

  • clang(LLVM 编译器)3.0 以上
  • objc4 Objective-C 运行时库 493.9 以上

以下内容待学

__strong 修饰符:

__weak 修饰符:

__autoreleasing 修饰符:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容