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 ...
随机推荐
- GCD 常用代码
GCD 常用代码 体验代码 异步执行任务 - (void)gcdDemo1 { // 1. 全局队列 dispatch_queue_t q = dispatch_get_global_queue(0, ...
- AngularJS启动过程分析
1111 app.controller('myCtrl',['$scope',function($scope){ $scope.wcrq=1234567890; }]); angular.bo ...
- C#数字格式化
格式规范的完整形式:{index [,width][:formatstring]} index是此格式程序引用的格式字符串之后的参数,从零开始计数:width(可选) 是要设置格式的字段的宽度,wid ...
- 再说vundle: 完全vim字符编程的四个必须插件 - zen coding 和emmet插件的使用
一个常识: 基本上vim插件的配置文集都是放在对应插件目录 的/autoload/ plugin_name.vim 文件中的 有四个必要/必须的插件,实现vim完全的字符界面的编程: NERDTree ...
- 深入理解Javascript面向对象编程
深入理解Javascript面向对象编程 阅读目录 一:理解构造函数原型(prototype)机制 二:理解原型域链的概念 三:理解原型继承机制 四:理解使用类继承(继承的更好的方案) 五:建议使用封 ...
- PHP输出缓冲(Output Buffering)
什么是缓冲区? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题~其实缓冲区最本质的作用就是,协调高速CPU和相对缓慢的IO设备 ...
- solr多条件查询(二)
由于现在的 需求很变态需要N多条件的叠加,本人就用了一天时间摸索加求助,终于参透出这个q和fq的强大之处. 需求如下图,有三种关系:并且.或.不含 1.如果是或者也就是改变的q的查询条件: 2.如果是 ...
- input lable水平对齐
1.CSS <style type="text/css"> input,label { vertical-align:middle;} </style ...
- 一张图告诉你,只会jQuery还不够!
会了jquery语法,会了jquery函数,你就真的会了jquery吗,来看这张图!是超实用的jquery代码段一书的导览!熊孩子们,赶紧学习去吧! 对于码农来说,代码就是生产力,你每天能码多少行并不 ...
- HDOJ 1711 Number Sequence
Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...