iPhone开发资料之内存管理 ,循环引用导致的内存问题

iPhone开发资料之内存管理 ,循环引用导致的内存问题

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447

 

http://en.wikipedia.org/wiki/Reference_counting

【IT168 技术文档】开发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无法发现的,所以要特别小心。

posted on 2012-06-06 18:05 linyawen 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/linyawen/archive/2012/06/06/2538622.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python能做大型游戏吗_python有做大型游戏的潜力吗?

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 岂止是有潜力,简直是很合适! 猪厂两大游戏客户端引擎,NeoX 和 Messiah,都使用 Python 作为脚本语言。 你最近所了解的比较火的挂着猪厂旗号的&a…

第4章 Python 数字图像处理(DIP) - 频率域滤波2 - 复数、傅里叶级数、连续单变量函数的傅里叶变换、卷积

目录基本概念复数傅里叶级数冲激函数及其取样(筛选)性质连续单变量函数的傅里叶变换卷积基本概念 复数 复数CCC的定义为 CRjI(4.3)C R jI \tag{4.3}CRjI(4.3) R,IR,IR,I为实数,RRR是实部,III是虚部,j−1j \sqrt{-…

不要迷失在技术的海洋中【转】

转自http://www.cnblogs.com/lovecherry/archive/2007/10/28/940555.html 不要迷失在技术的海洋中 技术就好像一片汪洋大海,越深入越望不到边际。就拿自己的体验来说吧,2000年的时候在学校搞ASP,觉得网页开发就是这么简单,把数据库…

使用代码设置Item级的权限(权限总结1)

itle in english:set Item Level Permission for SharePoint (MOSS/WSS) List/Document Library Programmatically 有些时候,我们需要为文档库里面某个文件设置特殊的权限,这个权限不继承自列表权限,当然最简单的最好是再创建一个列表&#…

echarts 4.0.4怎么下载_怎么让ECharts的提示框tooltip自动轮播?

1. 怎么让ECharts的提示框tooltip自动轮播?在用ECharts做大屏或者可视化展示项目的时候,让提示框tooltip自动轮播是比较常见的需求,给大家推荐一个插件叫echarts-tooltip-auto-show,名字是有点长,但是挺好用的。在hover显示tooltip之后&…

[React Native]高度自增长的TextInput组件

之前我们学习了从零学React Native之11 TextInput了解了TextInput相关的属性。 在开发中,我们有时候有这样的需求, 希望输入区域的高度随着输入内容的长度而增长, 如下: 这时候我们需要自定义一个组件: 在项目中创建AutoExpandingTextInput.js import …

网站开启Gzip压缩-apache

找到并打开apache/conf目录中的httpd.conf文件 httpd.conf中打开deflate_Module和headers_Module模块,具体做法为将 如下两句前面的#去掉:LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so 3.配置文…

第4章 Python 数字图像处理(DIP) - 频率域滤波3 - 取样和取样函数的傅里叶变换、混叠

目录取样和取样函数的傅里叶变换取样取样后的函数的傅里叶变换取样定理混叠由取样后的数据重建(复原)函数取样和取样函数的傅里叶变换 取样 fˉ(t)f(t)sΔT(t)∑n−∞∞f(t)δ(t−nΔT)(4.27)\bar f(t) f(t)s_{\Delta T}(t) \sum_{n-\infty}^{\infty}…

[转]Android开发,实现可多选的图片ListView,便于批量操作

本文转自:http://www.cnblogs.com/gergulo/archive/2011/06/14/2080629.html 之前项目需要实现一个可多选的图片列表,用户选中一到多张图片后,批量上传。但是网上有可多选普通列表的代码、也有单纯图片列表的代码,却没有两者合并的…

个人信息安全影响评估指南_发布 | 网络安全标准实践指南—移动互联网应用程序(App)收集使用个人信息自评估指南...

关于发布《网络安全标准实践指南—移动互联网应用程序(App)收集使用个人信息自评估指南》的通知信安秘字[2020] 40号各有关单位:为落实《网络安全法》相关要求,围绕中央网信办、工信部、公安部、市场监管总局联合制定的《App违法违规收集使用个人信息行为…

Go的50度灰:Golang新开发者要注意的陷阱和常见错误

Go的50度灰:Golang新开发者要注意的陷阱和常见错误 http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/

android intent和intent action大全

不管是页面牵转,还是传递数据,或是调用外部程序,系统功能都要用到intent。 在做了一些intent的例子之后,整理了一下intent,希望对大家有用。 由于intent内容太多,不可能真的写全,难免会有遗落&a…

第4章 Python 数字图像处理(DIP) - 频率域滤波4 - 单变量的离散傅里叶变换DFT

目录标题单变量的离散傅里叶变换由取样后的函数的连续变换得到DFT取样和频率间隔的关系单变量的离散傅里叶变换 由取样后的函数的连续变换得到DFT 对原函数的变换取样后的业的发展的变换F~(μ)\tilde F(\mu)F~(μ),但未给出取样后的函数f~(t)\tilde f(t)f~​(t)的…

在线生成 CSS3 的工具

1) CSS Creator – Layout Design 2) CSS Menu Maker 3) CSS3 Please 4) CSS3 Generator 5) CSS Border Radius 6) CSS3 Gradient Generator 7) CSS3 Button Generator 8 ) Mike Plate’s CSS3 Playground 9) Border Image Generator 10) CSS3 WRAP 11) Button Maker 12) Font…

python image 转成字节_就是这么牛!三行Python代码,让数据处理速度提高2到6倍

本文可以教你仅使用 3 行代码,大大加快数据预处理的速度。Python 是机器学习领域内的首选编程语言,它易于使用,也有很多出色的库来帮助你更快处理数据。但当我们面临大量数据时,一些问题就会显现……在默认情况下,Pyth…

sessionStorage 、localStorage 和 cookie 之间的区别(转)

essionStorage 、localStorage 和 cookie 之间的区别(转) 2012-05-08 14:29:19| 分类: HTML5CSS3WEBAPP|举报|字号 订阅 sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据。有了本地数据,…

删除文件夹里的图片,打印删除日志

1 #region 僵尸文件夹中的文件如果不在活文件列表中&#xff0c;删之2 List<string> deadfile new List<string>();3 foreach(string str in lstZombileDic)4 {5 if(Direct…

第4章 Python 数字图像处理(DIP) - 频率域滤波5 - 二变量函数的傅里叶变换、图像中的混叠、二维离散傅里叶变换及其反变换

目录二变量函数的傅里叶变换二维冲激及其取样性质二维连续傅里叶变换对二维取样和二维取样定理图像中的混叠二维离散傅里叶变换及其反变换二变量函数的傅里叶变换 二维冲激及其取样性质 两个连续变量的冲激函数定义为&#xff1a; δ(t,z){1,tz00,others(4.52)\delta(t, z) …

巧用VC工程下的rc文件

巧用VC工程下的rc文件(发表时间: 2008-12-30 17:20:00) 【评论】 【打印】 【字体&#xff1a;大 中 小】 本文链接&#xff1a;http://blog.pfan.cn/miaowei/40117.html 复制链接 分享到&#xff1a; 0标签:VC rc文件 资源文件 窗口尺寸设置 添加资源 纵观真个的VC工程&a…

蓝桥杯 参考题目 黄金队列(水题)

黄金分割数0.618与美学有重要的关系。舞台上报幕员所站的位置大约就是舞台宽度的0.618处&#xff0c;墙上的画像一般也挂在房间高度的0.618处&#xff0c;甚至股票的波动据说也能找到0.618的影子.... 黄金分割数是个无理数&#xff0c;也就是无法表示为两个整数的比值。0.618只…