《精通Objective-C》内存管理(及ARC) 阅读笔记

前言

前几天,《Objective-C高级编程》自动引用计数 阅读笔记 一文基本已经涉及到内存管理的各方面知识点,但是,在阅读《精通Objective-C》 第4章 内存管理的过程中,仍然可以学到不少东西,不仅仅是作者对于内存管理的另外一种理解方式,也从侧面反映出内存管理中不可或缺的重要的某些特性和要点。

Demo

Pro_Objective-C_ARC_Demo 提取码: i4p5

第4章 内存管理

问题1 对象引用和对象所有权

  • 通过指向Objective-C对象内存地址的变量(即*** 指针*** ),以*** 间接方式*** 访问Objective-C对象。在声明时,指针的名称中会带有*前缀。
  • 指针和间接访问方式可以应用于*** 所有Objective-C数据类型*** ,其中包括Objective-C的基本数据类型和C语言数据类型;然而,*** 对象指针*** 专门用于*** Objective-C对象的交互操作*** 。
  • 对象指针实现了Objective-C对象的访问功能,但是它们本身*** 不能管理所有权*** 。(因此,才需要内存管理机制)

问题2 内存管理基本原则(思考方式)

  • 自己生成的对象,自己持有(alloc/new/copy/mutableCopy方法群)
  • 非自己生成的对象,自己也能持有(使用retain方法)
  • 不再需要自己持有的对象时释放(可以使用release方法和autorelease方法)
  • 非自己持有的对象不能释放(会导致潜在的悬挂指针问题)

*** 内存管理思考方式的讲解可以参考《Objective-C高级编程》自动引用计数相关章节。***

问题3 使用自动引用计数(ARC)

  • ARC使用的引用计数模型与MRR使用的相同,但是由*** 编译器*** 管理回收对象(对象的生命周期)的工作。
  • ARC可以(潜在地)提升应用的性能和消除内存管理错误(如错误释放正在使用的对象,保留不再使用的对象)。
  • 与垃圾回收技术相比,ARC更可靠(保留和释放语句是在编译时插入的),并且不会为实现垃圾回收机制而在程序执行过程中引入暂停操作。
  • ARC可以Objective-C对象和块提供*** 自动内存管理*** 。
  • 由于ARC无法自动处理循环引用,Objective-C提供了*** 弱引用*** 功能,用于手动解除*** 循环引用*** 。

问题4 使用ARC的规则和约定

  • 不能手动编写发送*** retain、retainCount、release、autorelease和dealloc消息*** 的代码,但是,如果需要管理实例变量之外的资源,可以手动编写dealloc方法。
  • 不能直接进行*** id和(void *)类型的互转*** 。ARC只能管理Objective-C对象和块,因此编译器只能够处理Objective-C对象和块,而(void *)类型的指针是能够转换为任何指针类型(包括Objective-C中没有的指针类型)的通用指针,所以必须做此限制。
  • 在autoreleasepool块结束时,*** 自动释放由ARC管理的对象***
  • 不能调用Foundation框架中的*** NSAllocateObject函数*** 和*** NSDeallocateObject函数*** (因为这两个函数提供在指定内存区域中为对象分配和释放内存的功能,而Objective-C不再支持内存区,所以无法使用它们)。
  • 不能使用*** C结构中的对象指针*** 。
  • 不能使用*** 内存区(NSZone)*** 。
  • 为了与非ARC代码协作,不能创建*** 以copy开头的方法*** 和*** 自动声明属性*** 。
  • 默认情况下,ARC并非异常安全的:它无法释放异常失效的__strong变量,也无法在完整表达式抛出异常时,将位于该完整表达式末尾的对象释放。使用编译器选项*** -fobjc-arc-exceptions*** 可以启动处理ARC代码异常的功能。除非编译器解决了该异常,否则当弱引用异常失效是,ARC肯定会释放弱引用变量。

问题5 ARC的生命周期限定符(所有权修饰符)

*** 应用于常规变量的限定符 ***

  • __strong: *** 默认的限定符设置*** 。表明变量持有alloc/new/copy/mutableCopy方法群创建的对象的强引用,变量会在其作用域里被保留)。
  • __weak: *** 用于消除循环引用*** 。表明变量持有该对象的弱引用(即变量不持有该对象),对象随时可以被释放。当对象被释放后,附有__weak限定符的变量会被设置为nil。
  • __unsafe_unretained: 与__weak限定符类似。但是,在对象被释放后,指针(即变量)不会被设置为nil,而是会处于*** 悬挂状态*** (不再指向合法对象)。
  • __autoreleasing:*** 用于通过引用传递对象*** 。 alloc/new/copy/mutableCopy方法群以外的方法创建的对象,经编译器检查,会自动将返回值的对象注册到autoreleasepool中。

*** 应用于属性的限定符***

  • strong: 等同于retain特性。
  • weak: 类似于assign特性,但是如果引用对象被释放了,其实例变量会被设置为nil。

本章要点

介绍了Objective-C中的内存管理,其中包括Objective-C内存模型、为Objective-C程序分配和释放内存的方式,以及两种Objective-C内存管理机制的用法,要点有:

  • 在运行时,Objective-C程序创建的对象会以动态方式存储在预先分配的内存区域中,这片内存区域称为*** 堆内存 *** 。以动态方式创建对象意味着*** 需要管理内存*** ,因为在堆内存中创建的对象会一直使用该区域中的内存。不进行内存管理或者采用错误的内存管理方式,通常会导致*** 内存泄露*** 和*** 悬挂指针*** 问题。
  • Objective-C的内存管理是使用*** 引用计数*** 实现的,该技术通过对象的唯一引用判断对象是否正在被使用。如果某个对象的引用计数为0,那么就会被视为不再有用,运行时系统会释放它占用的内存。
  • 苹果公司的Objective-C开发环境提供两种内存管理机制:*** 手动管理(MRR)*** 和*** 自动引用计数(ARC)*** 。
  • 在使用MRR内存管理方式时,需要编写确切的代码,*** 管理对象的生命周期、获取对象(自己创建的或者需要持有的)所有权和释放对象(不再需要的)所有权*** 。
  • ARC使用的引用计数模型与MRR使用的引用计数模型相同,但是它通过*** 编译器*** 自动管理对象的生命周期。在编译程序时,编译器会分析源代码,确切以动态方式创建的对象生命周期,然后在已编译代码中自动插入必需的*** retain*** 和*** release*** 消息。
  • ARC中增加了新的对象生命周期限定符(也称所有权修饰符),使用这些限定符可以确切地声明对象变量和属性的生命周期,还可以实现弱引用功能(__weak修饰符),避免出现循环引用。
  • ARC能够以工程为单位应用,也能以文件为单位应用,因此ARC代码可以与非ARC代码共存。

第6章 专家级技巧:使用ARC

问题1 Objective-C直接桥接数据类型

Core Foundation数据类型 Foundation框架数据类型
CFArrayRef NSArray
CFDataRef NSData
CFDateRef NSDate
CFDictionaryRef NSDictionary
CFSetRef NSSet
CFStringRef NSString
CFMutableArrayRef NSMutableArray
CFMutableDataRef NSMutableData
CFMutableDictionaryRef NSMutableDictionary
CFMutableSetRef NSMutableSet
CFMutableStringRef NSMutableString
CFNumberRef NSNumber
CFReadStreamRef NSInputStream
CFWriteSteamRef NSOutputStream

问题2 ARC桥接转换

*** __bridge标记 ***
使用__bridge标记可以在*** 不改变所有权*** 的情况下,将对象从Core Foundation框架数据类型转换为Foundation框架数据类型(反之亦然)。注意,该标记无法解决*** 内存泄露*** 和*** 悬挂指针*** 问题。

*** __bridge_retained标记 ***
使用__bridge_retained标记可以将Core Foundation框架数据类型对象转换为Foundation框架数据类型对象,并从ARC接管对象的所有权。*** 手动管理*** 直接桥接数据的生命周期。

*** __bridge_transfer标记 ***
使用__bridge_transfer标记可以将Foundation框架数据类型对象转换为Core Foundation框架数据类型对象,并且会将对象的所有权交给ARC管理。这样,由*** ARC管理*** 对象的生命周期。

注意:

转换标记位于数据类型之前。ARC桥接转换不仅可以用于直接桥接数据类型,还可以用于*** 访问未分配给Objective-C对象的内存*** 。

本章要点

深入研究了ARC的内存管理方式,着重介绍了ARC中的对象所有权、块对象和直接桥接(Toll free bridging),要点有:

  • ARC*** 禁止*** 通过手动方式,向对象发送*** release、autorelease、dealloc消息以及与对象有关的其他消息*** 。
    当执行下列操作时,程序会放弃对象的所有权:
  1. *** 重新分配变量(变量执行另外一个对象)***
  2. *** 将nil赋值给变量***
  3. *** 释放对象的拥有者***
  • 当变量被更改为指向*** 另外一个对象*** 时,变量*** 原来的对象*** 会失去一个拥有者;在编译时,ARC会插入向该对象发送一条*** release消息*** 的代码。
  • 当指向对象的变量被设置为*** nil*** 时,该对象会失去一个拥有者;在编译时,ARC会插入向该对象发送一条*** release消息*** 的代码。
  • 当集合类实例被设置为nil时,集合类实例会被*** 释放*** ,ARC会自动向该集合类实例中的*** 每一个对象*** 发送一条*** release消息*** 。
  • 苹果所提供的基于C语言的API软件库没有与ARC整合,因此,在程序中以动态方式为这些API分配内存时,必须*** 手动管理内存*** (用到了*** __bridge_retained转换符*** )。
  • ARC禁止在Objective-C对象指针和其他类型指针之间标准转换,但是,通过多种机制(直接桥接和ARC桥接转换),可以使用在Objective-C程序中使用基于C语言的API。
  • 在使用ARC时,无法直接转换直接桥接的数据类型,必须使用特殊的ARC桥接转换标记(*** __bridge、__bridge_retained、__bridge_transfer*** )才能进行转换。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容