第五章:内存管理

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. webapi支持跨域访问

    写在前面 在实际应用中,跨域请求还是比较常见的,如何上接口直接支持跨域的访问呢? demo 场景项目A有个接口用来获取用户列表,现在项目b也有个功能需要加载用户列表.这两个项目在两个域名下,至少端口好 ...

  2. 分布式缓存之 memcache 实现分布式缓存

    最近想搞点分布式,但是不知道整点什么,来点简单的吧. 今天讲下memcache的分布式缓存 首先下载memcache的服务器端 百度下可以找到 然后执行安装和开启(关闭服务器)命令(还有其他的命令 可 ...

  3. Mastering Web Application Development with AngularJS 读书笔记(三)

    第一章笔记 (三) 一.Factories factory 方法是创建对象的另一种方式,与service相比更灵活,因为可以注册可任何任意对象创造功能.例如: myMod.factory('notif ...

  4. VPN添加静态路由表(指定程序或资源走VPN)

    在某此情况下,我们希望为VPN客户端指定线路,比如只有公司的资源或网站才使用VPN连接,其它的网络请求依然走他们自己的默认网关. 这种情况下,我们就需要给VPN客户端添加静态路由规则并取消VPN连接的 ...

  5. jquery Ajax跨域调用WebServices方法

    由于公司需要开发一个手机页面,想提供给同事直接在手机上可以查询SAP资料.数据需要使用js调用webserver来获取. 因为初次使用Jquery调用Webserver,所以期间并不顺利.测试调用We ...

  6. runtime(面试)

    运行时机制,runtime库里面包含了跟类.成员变量.方法相关的API,比如获取类里面的所有成员变量,为类动态添加成员变量,动态改变类的方法实现,为类动态添加新的方法等 需要导入<objc/me ...

  7. 改造 ThinkPHP,弃用 D() 等魔术函数

    ThinkPHP 是国内比较优秀的 PHP 框架,但有些地方不是很好,比如那些 魔术函数 D(),用它返回的类实例,在各个IDE(如 PhpStorm)下根本识别不了,导致如下问题: 1.不支持 代码 ...

  8. python spark 配置

    前提:已经装好 java 1.8 和 hadoop 2.7 1. 下载解压放后的目录 /Users/gao/spark-1.4.1-bin-hadoop2.6 2. 在~/.bash_profile ...

  9. cocos2dx 3.7中 AppDelegate.h的class TestController;这种写法的具体意思不太明白,只能猜是类似于外部定义的东西。

    cocos2dx 3.7中 AppDelegate.h的class TestController;这种写法的具体意思不太明白,只能猜是类似于外部定义的东西.

  10. maven项目部分知识

    1.maven项目在pom.xml中用add dependencies加入jar包,搜索不到jar包的解决方案: Window  --> Show View --> Other输入mave ...