做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作的理解是衡量一个程序员成熟与否的一个标准。好了,闲话不说,下面进入正题。 众所周知,ObjectiveC的内存管理引用的一种叫做“引用计数“ (Reference Count)的操作方式,简单的理解就是系统为每一个创建出来的对象,(这里要注意,只是对象,NSObject的子类,基本类型没有‘引用计数’)记录一个引用计数,初始化这个对象的时候会调用alloc方法,系统在alloc方法里会将这个对象的引用计数+1;例如:UIView *myview = [UIView alloc] init]; 这里创建的对象myview它现在的引用技术就是1。所有的对象可以调用[xxx reatin];来使自身的引用计数+1。也可以调用[xxx release];让自身的引用计数-1.如果一个对象的引用计数为0,那么这个对象立即(记住,是立即)会被系统回收掉。除了[xxx reatin];会将对象的引用计数+1之外还有很多方法会将对象的引用技术+1,举两个最常用的:[self.view addSubView:myView];这个方法会将myView的引用计数+1。 NSArray类里的[array addObject:myView];也会将引用计数+1。下面我会用代码说明一下几个比较容易出错的地方。
(一)临时变量对象的引用计数说明
UIView *v = [[UIView alloc] init]; //分配后引用计数为1
- [self.view addSubview:v]; //这儿引用计数加1,为2
- [v release]; //这儿引用计数为-1为1
- 最后系统在回收self.view的时候,会先回收其subView,所以self.view被回收时v的引用计数是0,v就会立即被回收。
(二)成员变量对象的引用计数说明
- v = [[UIView alloc] init];
- [self.view addSubview:v];
- [v release];
- 如果在dealloc里调用了[v release];那么就多release了,会crash.
(三)如果v是类的属性,并且是声明的时候是assgin
- @property (nonatomic, assign) UIView *v; 这儿是assign, 然后分配内存的时候如果是这样
- self.v = [[UIView alloc] init];//计数为1
- [self.view addSubview:self.v];//计数为2
- [self.v release];//计数为1
- 这时不需要在dealloc里[self.v release];因为assign声明的对象引用计数不会自动+1.当self.view被回收时,self.v的引用计数就会变成0;V就会被系统回收掉。
(四)如果v是类的属性,并且是声明的时候是reatin的
- @property (nonatomic, retain) UIView *v; 或 @property (nonatomic, copy) UIView *v;声明的属性,那么这样分配内存
- v = [[UIView alloc] init];
- [self.view addSubview:v];
- [v release];这样与a是一样情况,不需要在dealloc里释放。
- 但如果是
- self.v = [[UIView alloc] init];
- [self.view addSubview:self.v];
- [self.v release];加了个self,那么就要在dealloc里[v release];因为如果属性用reatin声明的时候,用self.初始化的时候对象的引用技术会自动+1。self.v = [[UIView alloc] init];//这个时候引用计数为2
下面聊聊autorelease,autorelease是objectiveC语言的一个比较特殊的机制,也是理解ObjectiveC内存管理的关键,Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。对的,其实autorelease就是一个延迟释放的机制,比较好的介绍autorelease的文章:http://developer.51cto.com/art/201007/212523.htm 这篇文章个人认为autorelease讲解的比较详细,也易于理解。推荐大家看看,这里除了这篇文章之外我还要谈谈我对autorelease的一些理解。我理解的是,系统在执行每一个函数的时候,会自动开启一个autoreleasePool(记住是每一个函数的运行都会开启一个autoreleasePool,而不是每一个类开启一个,这一点很关键),在这个函数当中创建的所有用autorelease声明的对象都会放进这一个的池当中。当函数运行完的时候,这一个autorelasepool 会被drain 掉,那么池中所有引用计数为0的(千万记住是引用计数为0)对象,就会被系统回收掉。写到这里很多人就会程序猿就会质疑我这个说法了,比如我在某一个UIViewController类的viewDidLoad函数里面写了:UIView *myView = [[UIView alloc] init] autorelease];[self.view addsubView:myView]; 的时候,当viewDidLoad函数执行完,为什么myView对象没有被回收。这是因为:因为调用了[self.view addsubView:myView];所以这时myView的引用计数变成了2,当函数执行完,autorelease被drain掉的时候,自动释放池内所有的对象都会调用release方法,这时所有的对象的引用计数-1,如果这时对象的引用计数为0那么它会被系统回收,如果不为0,那么他还回被保留,也就是说自动释放池中的对象不会因为自动释放池的销毁而被销毁,自动释放池的对象只是被延迟释放了,池中对象的释放也得满足引用计数的机制。
[转载]对iOS开发中内存管理的一点总结与理解的更多相关文章
-
IOS开发的内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
-
IOS开发小记-内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
-
(转)iOS开发ARC内存管理技术要点
转自:http://www.cnblogs.com/flyFreeZn/p/4264220.html 本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automati ...
-
iOS开发ARC内存管理技术要点
本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...
-
IOS开发之内存管理--dealloc该写些什么
在非ARC开发环境中,dealloc是类释放前,清理内存的最后机会.到底那些变量和属性该释放呢,一些特殊的类(nstimer,observer)该怎么释放.需要注意的是不释放会引起内存泄露,过度释放也 ...
-
iOS开发ARC内存管理
本文的主要内容: ARC的本质 ARC的开启与关闭 ARC的修饰符 ARC与Block ARC与Toll-Free Bridging ARC的本质 ARC是编译器(时)特性,而不是运行时特性,更不是垃 ...
-
ARM裸机开发中内存管理库RT_HEAP的使用
在使用arm芯片进行裸机开发的时候,很多时候都需要内存管理的功能,我们可以使用自己写的内存管理程序,也可以直接使用标准库,不过我一般比较喜欢标准库,速度快,今天就来说说在C语言环境下怎么样进行内存的动 ...
-
iOS开发--漫谈内存管理(一)
1.MRC与ARC 苹果提供两种内存管理机制:一种是MRC(manual reference count),即手动引用计数:还有一种是ARC(auto reference count).即自己主动引用 ...
-
iOS开发中遇到的一些问题及解决方案【转载】
iOS开发中遇到的一些问题及解决方案[转载] 2015-12-29 [385][scrollView不接受点击事件,是因为事件传递失败] // // MyScrollView.m // Creat ...
随机推荐
-
UISlider显示进度(并且实现图片缩放)
图片展示效果如下: 其他没什么好说的,直接上代码: RootView.h: #import <UIKit/UIKit.h> @interface RootView : UIView @pr ...
-
DataGridView 些许事件测试
原始设计需求:当单元格内容是空白时,鼠标进入之后,显示一些数据 直观的第一感觉必然是用CellClick,细想,如果用户不用鼠标,直接按Tab键切换单元格呢?又或者,用户直接双击涅~ 主要测试的是: ...
-
boost muti-thread
背景 • 今天互联网应用服务程序普遍使用多线程来提高与多客户链接时的效率:为了达到最大的吞吐量,事务服务器在单独的线程上运行服务程序: GUI应用程序将那些费时,复杂的处理以线程的形式单独 ...
-
asp.net微信开发第二篇----消息应答
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上. 请注意: 1.关于重试的消息排重,推荐使用msgid排重. 2.微信服务器在五秒内收不到响应会断掉连接 ...
-
tinkphp5.0 traits 的引入
Traits引入 ThinkPHP 5.0开始采用trait功能(PHP5.4+)来作为一种扩展机制,可以方便的实现一个类库的多继承问题. trait是一种为类似 PHP 的单继承语言而准备的代码复用 ...
-
thinkphp实现无限级分类
普通的方法(采用for和foreach) //显示 foreach($data as $k=>$v){ //str_repeat()函数用于把字符串重复指定的次数 $data[$k]['titl ...
-
html2canvas页面截图图片不显示
前两天在一个群里,有人问使用html2canvas屏幕截图的时候为什么页面的图片不显示只显示了文字,我没有做过屏幕截图的需求,所以不是很清楚,今天稍稍测试了一下. 在github上将html2canv ...
-
codeforces 761B Dasha and friends
https://vjudge.net/problem/CodeForces-761B 题意: 有一个圆形跑道,上面有若干个障碍,分别给出两个人距离障碍的距离,问这两个人是否是在同一个跑道上跑步(我是这 ...
-
Redis之(一)初识Redis
1.Redis概述 我们知道,内存是电脑主板上的存储部件,用于存储当前正在使用的数据和程序,CPU可以与内存直接沟通,所以访问速速非常高:而外存数据必须加载到内存以后程序才能使用.如果把CPU当做一个 ...
-
Spring MVC 使用介绍(八)—— 类型转换
一.概述 spring类型转换有两种方式: PropertyEditor:可实现String<--->Object 之间相互转换 Converter:可实现任意类型的相互转换 类型转换的过 ...