第五章:内存管理

29 理解引用计数

30 以ARC简化引用计数

总结:ARC通过命名约定将内存管理规则标准化。其他编程语言很少像OC这样强调命名。ARC通过设置全局数据结构(此数据结构的具体内容因处理器而异)中的一个标志位,来代替直接调用autorelease和retain。这是ARC所带来的好处。待编译器与运行期组件日臻成熟,还会出现其他的优化技术。CoreFoundation对象不归ARC管理,开发者必须适时调用CFRetain/CFRelease。

31 在dealloc方法中只释放引用并解除监听

总结:

- (void)dealloc{

CFRelease(coreFoundationObject);

[[NSNotificationCenter defaultCenter] removeObserver:self];

}

虽然说应该在dealloc中释放引用,但是开销较大或系统内稀缺的资源则不在此列。譬如文件描述符(file descriptor),套接字(socket),大块内存。不能指望dealloc必定会在某个特定时机调用,因为有一些无法预料的东西可能也持有此对象。应当当应用程序用完资源对象后,就调用清理方法。也要在- (void)applicationWillTerminate:(UIApplication *)application里面调用清理方法。

- (void)close{

_closed = YES;

}

- (void)dealloc{

if(!_closed = YES){

NSLog(@“ERROR:close was not called before dealloc”);

//有时候不想只输出错误消息,而是要抛出异常来表明不调用close方法是严重的编程错误

[self close];

}

}

虽然不要在dealloc里随便调用其他方法,但是这是为了侦测编程错误而破例。

在dealloc里也不要调用属性的存取方法,因为有人可能会覆写这些方法,并于其中做一些无法在回收阶段安全执行的操作。在dealloc方法里,应该做的事情就是释放指向其他对象的引用,并取消原来订阅的键值观测或NSNotificationCenter等通知。如果对象持有文件描述符等系统资源,那么应该专门编写一个方法来释放此中资源。这样的类要和其他使用者约定:用完资源后必须调用close方法。执行异步任务的方法不应在dealloc里调用;只能在正常状态下执行的那些方法也不应在dealloc里调用,因为此时对象已处于正在回收的状态了。

32 编写异常安全代码时留意内存管理问题

总结:捕获异常时,一定要注意将try块内所创立的对象清理干净。在默认情况下,ARC不生成安全处理异常所需的清理代码。开启编译器标志后,可生成这种代码,不过会导致应用程序变大,而且会降低运行效率。有时用OC++来编码,或是编码中用到了第三方程序库而此程序库所抛出的异常又不受你控制时,就需要捕获及处理异常了。如果手工管理引用计数,而且必须捕获异常,那么要设法保证所编代码能把对象正确清理干净。若使用ARC且必须捕获异常,则需打开编译器的-fobjc-arc-exceptions标志。但最重要的是,在发现大量异常捕获操作时,应考虑重构代码。用NSError式错误信息来取代异常。

33 以弱引用避免保留循环

总结:一般来说,如果不拥有某对象,就不要保留它。这条规则对collection例外,collection虽然并不直接拥有其内容,但是它要代表自己所属的那个对象来保留这些元素。有时,对象中的引用会指向另外一个并不归自己拥有的对象。比如delegate模式。weak引用的自动清空是随着ARC而引入的新特性,由运行期系统来实现。在具备自动清空的弱引用上,可以随意读取其数据,因为这种引用不会指向已经回收过的对象。

34 以自动释放池块降低内存峰值

总结:虽然自动释放池块的开销不太大,但毕竟还是有的,所以尽量不要建立额外的自动释放池。NSAutoreleasePool更为重量级,不会在每次执行for循环时都清空池,通常用来创建那种偶尔需要清空的池。自动释放池块更为轻量级,可以每次执行循环时都会建立并清空自动释放池。自动释放池排布在栈中,对象收到autorelease消息后,系统将其放入最顶端的池里。合理运用自动释放池,可降低应用程序的内存峰值。(需要消耗大量的资源,内存,CPU的是重量级,量级主要是看对容器的依赖性所决定的,依赖性越小,越轻量)

35 用僵尸对象调试内存管理问题

总结:NSZombieEnabled = “YES”;其实就是做dealloc方法所做的事情,运行期将dealloc调配成zombie的版本。系统给每个变为僵尸的类都创建一个对应的新类。给僵尸对象发消息后,系统可由此知道该对象原来所属的类。如果把所有僵尸对象都归到_NSZombie_类里,那原来的类名就丢了。创建新类的工作由运行期函数objc_duplicateClass()完成,会把整个_NSZombie_类的结构拷贝一份,并赋予其新的名字。副本类的超类,实例变量及方法都和复制前相同。还有种做法也能保留旧类名,那就是不拷贝_NSZombie_而是创建继承自 (轻量级的)_NSZombie_的新类,但是用相同的函数完成此功能,其效率不如直接拷贝高。由于_NSZombie_没有实现任何方法,所以发给他的全部消息都要经过“完整的消息转发机制“。系统会修改对象的isa指针,令其指向特殊的僵尸类,从而使该对象变为僵尸对象。僵尸类能响应所有的选择子。响应方式为:打印一条包含消息内容及其接收者的消息,然后终止程序。

36 不要使用retainCount

总结:retain count永远不会返回0。@“somestring”保留计数是2的64-1 @1保留计数是2的63-1 @3.141f 。单例对象的保留计数绝对不会变,这种对象的保留及释放都是空操作。即便两个单例对象之间,其保留计数也各不相同。永远不要使用保留计数。

effective OC2.0 52阅读笔记(五 内存管理)的更多相关文章

  1. effective OC2.0 52阅读笔记(七 系统框架)

    47 熟悉系统框架 总结:将代码封装为动态库,并提供接口的头文件,就是框架.平时的三方应用都用静态库(因为iOS应用程序不允许在其中包含动态库),并不是真正的框架,然而也经常视为框架.例如:NSLin ...

  2. effective OC2.0 52阅读笔记(六 块与大中枢派发)

    派发队列:dispatch_queue 操作队列:NSOperationQueue  组:dispathc_group_t 37 理解“块”这一概念 总结:块就是一个值,且自有其相关类型.块的强大之处 ...

  3. effective OC2.0 52阅读笔记(三 接口与API设计)

    第三章:接口与API设计 15 用前缀避免命名空间冲突 总结:避免重名符号错误的唯一办法是变相实现命名空间.为所有符号都加上命名前缀.类和分类都应加三字前缀.注意类实现文件中的纯C函数及全局变量,是算 ...

  4. effective OC2.0 52阅读笔记(二 对象、消息、运行期)

    第二章:对象.消息.运行期 6 理解属性这一概念 总结:OC解决硬编码偏移量问题的做法,一种方案是把实例变量当做一种存储偏移量所用的特殊变量,交由类对象保管,偏移量会在运行期查找,叫做稳固的“应用程序 ...

  5. effective OC2.0 52阅读笔记(一 熟悉Objective-C)

    第一章:熟悉Objective-C 1 了解objective-c语言的起源 总结:OC为C语言添加了面向对象的特性,是其超集.采用动态绑定的消息结构而非函数调用,也就是说,要在运行时才检查对象类型及 ...

  6. effective OC2.0 52阅读笔记(四 协议与分类)

    23 通过委托与数据源协议进行对象间通信 总结:委托模式的常规委托模式中,信息从类Class流向受委托者delegate.数据源模式,信息从数据源datasource流向class.数据源和受委托者可 ...

  7. Mongodb Manual阅读笔记:CH4 管理

    4 管理 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb Manual阅读笔 ...

  8. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  9. Linux学习笔记(五) 账号管理

    1.用户与组账号 用户账号:包括实际人员和逻辑性对象(例如应用程序执行特定工作的账号) 每一个用户账号包含一个唯一的用户 ID 和组 ID 标准用户是系统安装过程中自动创建的用户账号,其中除 root ...

随机推荐

  1. iOS-设置UIPageControl 显示图片

    UIPageControl 的默认样式是几个小圆点,系统没有提供属性供我们自定义这几个小圆点的样式,不过我们依然可以使用KVC来自定义PageControl的显示样式 UIPageControl *p ...

  2. 【8-23】node.js学习笔记

    Node入门 //请求(require)Node.js自带的 http 模块,并且把它赋值给 http 变量 //变成了一个拥有所有 http 模块所提供的公共方法的对象 var http = req ...

  3. java.lang.reflect.Field

    java.lang.reflect.Field 一.Field类是什么 Field是一个类,位于java.lang.reflect包下. 在Java反射中 Field类描述的是 类的属性信息,通俗来讲 ...

  4. oracle中的连接查询与合并查询总结

    连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积:   (各 ...

  5. getStyle(),修改样式属性

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 湖南附中模拟day1 收银员

    4.1 题意描述花花家的超市是 24 小时营业的,现在需要招聘收银员.超市每个小时都需要不同数量的收银员,用 ai 表示一天中 i 点到 i + 1 点这一小时内需要的收银员数量,特别地 a23 表示 ...

  7. 一段可以使用的 hibernate获得对象->action存入List->jsp页面用<s:iterator>迭代的代码

    SelectAction.java @SuppressWarnings("serial") @Component("selectAction") @Scope( ...

  8. 自己总结的USB数据结构及其描述符

    背景: USB理论知识光看着空想总觉着丢三落四,好像哪里没法理解到位,自己做个总结. 正文: 1. USB通信的最基本单位是“包”.如果把“包”肢解的话,可以分为各种“域”(7类,即一串二进制数.每类 ...

  9. cf558c(bfs)

    C. Amr and Chemistry time limit per test 1 second memory limit per test 256 megabytes input standard ...

  10. 高性能滚动 scroll 及页面渲染优化

    最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...