effective OC2.0 52阅读笔记(五 内存管理)
第五章:内存管理
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阅读笔记(五 内存管理)的更多相关文章
- effective OC2.0 52阅读笔记(七 系统框架)
47 熟悉系统框架 总结:将代码封装为动态库,并提供接口的头文件,就是框架.平时的三方应用都用静态库(因为iOS应用程序不允许在其中包含动态库),并不是真正的框架,然而也经常视为框架.例如:NSLin ...
- effective OC2.0 52阅读笔记(六 块与大中枢派发)
派发队列:dispatch_queue 操作队列:NSOperationQueue 组:dispathc_group_t 37 理解“块”这一概念 总结:块就是一个值,且自有其相关类型.块的强大之处 ...
- effective OC2.0 52阅读笔记(三 接口与API设计)
第三章:接口与API设计 15 用前缀避免命名空间冲突 总结:避免重名符号错误的唯一办法是变相实现命名空间.为所有符号都加上命名前缀.类和分类都应加三字前缀.注意类实现文件中的纯C函数及全局变量,是算 ...
- effective OC2.0 52阅读笔记(二 对象、消息、运行期)
第二章:对象.消息.运行期 6 理解属性这一概念 总结:OC解决硬编码偏移量问题的做法,一种方案是把实例变量当做一种存储偏移量所用的特殊变量,交由类对象保管,偏移量会在运行期查找,叫做稳固的“应用程序 ...
- effective OC2.0 52阅读笔记(一 熟悉Objective-C)
第一章:熟悉Objective-C 1 了解objective-c语言的起源 总结:OC为C语言添加了面向对象的特性,是其超集.采用动态绑定的消息结构而非函数调用,也就是说,要在运行时才检查对象类型及 ...
- effective OC2.0 52阅读笔记(四 协议与分类)
23 通过委托与数据源协议进行对象间通信 总结:委托模式的常规委托模式中,信息从类Class流向受委托者delegate.数据源模式,信息从数据源datasource流向class.数据源和受委托者可 ...
- Mongodb Manual阅读笔记:CH4 管理
4 管理 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb Manual阅读笔 ...
- linux kernel学习笔记-5内存管理_转
void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...
- Linux学习笔记(五) 账号管理
1.用户与组账号 用户账号:包括实际人员和逻辑性对象(例如应用程序执行特定工作的账号) 每一个用户账号包含一个唯一的用户 ID 和组 ID 标准用户是系统安装过程中自动创建的用户账号,其中除 root ...
随机推荐
- HttpUtility.UrlEncode 和 HttpUtility.Encode 一个大深坑
进行了 Encode 之后 在解码(UrlEncode )之后 + 号莫名的变成了空格, 需要执行一个replace 操作
- PHP常用的一些正则表达式
附一些常用的正则运算: 验证数字:^[0-9]*$验证n位的数字:^\d{n}$验证至少n位数字:^\d{n,}$验证m-n位的数字:^\d{m,n}$验证零和非零开头的数字:^(0|[1-9][0- ...
- CF467 AB 水题
Codeforces Round #267 (Div. 2) (C和D的题解单独写:CF467C George and Job (DP) CF467D Fedor and Essay 建图DFS) C ...
- socket编程报异常java.io.EOFException
一个客户端连接服务器的小程序,服务器端可以正常读取客户端发来的数据 但是当客户端关闭时,服务端也关闭了,并且抛出如下的异常: java.io.EOFException at java.io.DataI ...
- git checkout -b 的详细讲解
创建分支: $ git branch mybranch 切换分支: $ git checkout mybranch 创建并切换分支: $ git checkout -b mybranch 更新mast ...
- 2015年12月01日 GitHub入门学习(二)手把手教你Git安装
序:Mac与Linux中,Mac都预装了Git,各版本的Linux也都提供了Git的软件包.下面手把手教你Windows下的安装. 一.Git Windows GUI 下载地址 msysgit htt ...
- python的re正则表达式模块学习
python中re模块的用法 Python 的 re 模块(Regular Expression 正则表达式)提供各种正则表达式的匹配操作,在文本解析.复杂字符串分析和信息提取时是一个非常有用的工 ...
- xcode的调试技巧
转自:http://www.cnblogs.com/daiweilai/p/4421340.html#biyouji 目录 前言逼优鸡知己知彼 百战不殆抽刀断Bug 普通操作 全局断点(Global ...
- XML理解
XML:页面之间传递数据,跨平台传递,核心标签 HTML:超文本标记语言,核心标签 <xml version='1.0'>版本1.0<Nation> <one> & ...
- SRM 513 2 1000CutTheNumbers(状态压缩)
SRM 513 2 1000CutTheNumbers Problem Statement Manao has a board filled with digits represented as St ...