`
jiagou
  • 浏览: 2525676 次
文章分类
社区版块
存档分类
最新评论

iPhone开发内存管理

 
阅读更多

开发iPhone 应用程序并不难,基本上就是三个词 – “memory, memory, memory” 。iPhone OS 对内存的要求很严格,有memory leak ,杀掉; 内存使用超限额,杀掉。一个经过测试的程序,在使用过程中90%以上的崩溃都是内存问题造成的。在这里简单总结一下Object-C 内存管理。

基本概念

Object-C 的内存管理基于引用计数(Reference Count)这种非常常用的技术。简单讲,如果要使用一个对象,并希望确保在使用期间对象不被释放,需要通过函数调用来取得“所有权”,使用结束后再调用函数释放“所有权”。“所有权”的获得和释放,对应引用计数的增加和减少,为正数时代表对象还有引用,为零时代表可以释放。

函数

获得所有权的函数包括

  • alloc– 创建对象是调用alloc,为对象分配内存,对象引用计数加一。
  • copy– 拷贝一个对象,返回新对象,引用计数加一。
  • retain– 引用计数加一,获得对象的所有权。

另外,名字中带有alloc, copy, retain 字串的函数也都认为会为引用计数加一。

释放所有权的函数包括

  • release– 引用计数减一,释放所有权。如果引用计数减到零,对象会被释放。
  • autorelease– 在未来某个时机释放。下面具体解释。

autorelease

在某些情况下,并不想取得所有权,又不希望对象被释放。例如在一个函数中生成了一个新对象并返回,函数本身并不希望取得所有权,因为取得后再没有机会释放(除非创造出新的调用规则,而调用规则是一切混乱的开始),又不可能在函数内释放,可以借助autorelease 。所谓autorelease , 可以理解为把所有权交给一个外在的系统(这个系统实际上叫autorelease pool),由它来管理该对象的释放。通常认为交给 autorelease 的对象在当前event loop 中都是有效的。也可以自己创建NSAutoreleasePool 来控制autorelease的过程。

据苹果的人说,autorelease效率不高,所以能自己release的地方,尽量自己release,不要随便交给autorelease来处理。

规则

引用计数系统有自己的引用规则,遵守规则就可以少出错:

  • 获得所有权的函数要和释放所有权的函数一一对应。
  • 保证只有带alloc, copy, retain 字串的函数才会让调用者获得所有权,也就是引用计数加一。
  • 在对象的 dealloc函数中释放对象所拥有的实例变量。
  • 永远不要直接调用dealloc来释放对象,完全依赖引用计数来完成对象的释放。

有很多类都提供“便利构造函数(convenience constructors)”,它们创建对象但并不增加引用计数,意味着不需要调用release来释放所有权。很好辨认,它们的名字中不会有alloc和copy。

只要遵守这些规则,基本上可以消除所有Intrument可以发现的内存泄露问题。

容器

类似NSArray, NSDictionary, NSSet 等类,会在对象加入后引用计数加一获得所有权,在对象被移除或者整个容器对象被释放的时候释放容器内对象的所有权。类似的情况还有UIView对subview的所有权关系,UINavigationController对其栈上的controller的所有权关系等等。

其他所有权的产生

还有一些用法会让系统拥有对象的所有权。比如NSObject 的performSelector:withObject:afterDelay 。如果有必要,需要显示的调用cancelPreviousPerformRequestsWithTarget:selector:object: ,否则有可能产生内存泄露。

因这种原因产生的泄露因为并不违反任何规则,是Intrument所无法发现的。

循环引用

所有的引用计数系统,都存在循环应用的问题。例如下面的引用关系:

  • 对象a创建并引用到了对象b.
  • 对象b创建并引用到了对象c.
  • 对象c创建并引用到了对象b.

这时候b和c的引用计数分别是2和1。当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。

这种情况,必须打断循环引用,通过其他规则来维护引用关系。比如,我们常见的delegate往往是assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。如果一个UITableViewController 对象a通过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate又是a, 如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。

因为循环引用而产生的内存泄露也是Instrument无法发现的,所以要特别小心。


分享到:
评论

相关推荐

    ios iphone开发-内存管理

    ios iphone开发-内存管理 所有权是iPhone内存管理的核心思想,对象的所有者负责在使用完对象后进行释放。一个对象可以有多个所有者,当它没有所有者时将被设置为取消分配(deallocation)

    iPhone内存管理

    详细且全面地讲述了iPhone开发中的内存管理技术

    iphone开发官方指南-内存管理编程指南

    有大大弄成docx格式,我转换成pdf格式再次上传

    移动互联网开发笔记 VOL 2

    刊首语 征稿 在Android平台下定制系统的主屏幕 IPhone开发内存管理  Three20的使用 iOS开发者计划申请流程攻略 雅虎画报IPad版本的开发经验介绍

    iPhone 应用开发中Object-C 内存管理--千锋培训

    文档介绍了简介,基本概念,函数,获得所有权的函数包括,释放所有权的函数包括,规则,容器,其他所有权的产生,,循环引用

    iPhone开发基础教程

    Objective-C是扩展C的面向对象编程语言,也是iPhone开发用到的主要语言。. 本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及...

    iphone开发入门经典源码

    3.3 l 声明变量 3.3.2 分配、初始和释放对象 3.3 13使用方法及发送消息 3.3.4 表达式和决策 3.4 内存管理 34.1 释放对象 3.4.2 使用autorclease方法 3.4.3 保留对象 3.4.4 在dealloc中释放实例变量 34.5 释放规则 ...

    Objective-C高级编程 iOS与OS X多线程和内存管理

    帮助学习关于OC中内存管理的知识点

    IPhone开发常用技术笔记汇总

    本压缩包中包含了Iphone开发中常用到的技术总结笔记,五六十中技术方法以及季节方案,包括内存管理,方法回调,获取当前地点,自定义CELL,VIew圆角等等等,太多的奶水包,是我开发中所有的精华所在,只有你不知道的...

    iphone开发笔记

    退回输入键盘 2 CGRect 2 CGPoint & CGSize 3 设置透明度 3 设置背景色 3 自定义颜色 3 竖屏 3 横屏 3 状态栏高 3 导航栏、工具栏高 3 ...Objective-C内存管理 44 iphone更改键盘右下角按键的type 45

    《iPhone开发实战》.(Christopher Allen).pdf

     本书适合所有 iphone开发人员学习参考。... 目录 第一部分 iphone编程简介. 第1章 iphone简介2 1.1 iphone核心规范3 1.1.1 iphone的输入及输出规范3 1.1.2 iphone网络规范4 1.1.3 iphone浏览器规范5...

    iphone开发进阶

    iphone开发进阶 简要介绍iphone os的4个主要部分组成、OBJC的内存管理、归档、容器; 定制UIButton、视图切换、屏幕的触摸事件检测、使用SQLLite连接数据库等等

    object c/iphone 开发 试题

    16.内存管理 ①:程序A里有一段内存被成功申请完成之后,内存计数器就从0变为1 (这个过程是alloc); ②:然后程序B里也要使用这个内存,那么内存计数器从1变为2 (这个过程是retain); ③:紧接着程序A不需要这个内存...

    iPhone开发秘籍.part2.rar

    1.8.3 关于示例代码和内存管理的 注意事项.....18 1.9 构建Hello World 应用程序.....19 1.9.1 创建iPhone 项目.....19 1.9.2 运行主干.....20 1.9.3 定制iPhone 项目.....20 1.9.4 编辑标识信息.....21 1.9.5 使用...

    iPhone开发秘籍.part1.rar

    1.8.3 关于示例代码和内存管理的 注意事项.....18 1.9 构建Hello World 应用程序.....19 1.9.1 创建iPhone 项目.....19 1.9.2 运行主干.....20 1.9.3 定制iPhone 项目.....20 1.9.4 编辑标识信息.....21 1.9.5 使用...

    iPhone开发秘籍.part4.rar

    1.8.3 关于示例代码和内存管理的 注意事项.....18 1.9 构建Hello World 应用程序.....19 1.9.1 创建iPhone 项目.....19 1.9.2 运行主干.....20 1.9.3 定制iPhone 项目.....20 1.9.4 编辑标识信息.....21 1.9.5 使用...

    iphone3开发基础教程

    4.9 成为出色的内存使用者 67 4.10 小结 68 第5章 自动旋转和自动调整大小 70 5.1 使用自动调整属性处理旋转 71 5.1.1 指定旋转支持 71 5.1.2 使用自动调整属性设计界面 73 5.1.3 自动调整属性 74 5.1.4 设置按钮的...

Global site tag (gtag.js) - Google Analytics