源地址: http://www.ityran.com/article-89-1.html
摘要: 很多系统的方法,比如、等等返回的对象都是autorelease对象,这些对象是不需要手动释放的,如果手动释放会导致程序崩溃!切记!,原则就是系统中所有没有使用alloc、copy、retain来创建的对象都是autorelease对象, ...
本文由fel835(泰然管理团队成员)原创,转载请注明出处并通知泰然。
很多童鞋对于IOS中的内存管理处理的不好,有时候感觉自己已经掌握了,其实用起来的时候往往出现很多的内存泄露或者因为内存管理的不恰当导致程序崩溃!网上有一片很详细的内存管理文章,很多人估计嫌长,不愿意去看,我就写一个简单易懂的分享。 我分四块来讲解,这篇文章比较简单,因为我不想把你们搞晕,其实总的来说就一个原则! 一、IOS内存管理的机制 IOS中没有垃圾回收机制(IOS5中好像已经有了,但是目前还不太实用),所以基本一切都是自己手动管理。 IOS中采用引用计数的内存管理方式,啥意思呢?讲的通俗点就是说一块内存地址是否应该被释放是又retaincount来决定的,如果这块内存地址的retaincount为0,那么这块内存就会被释放,再也找不到了。 所以想让他一直存在,那么它的retaincount就必须大于0。 那么如何管理呢?其实原理非常简单,就是谁用谁retain,谁retain的谁release,遵循这个原则的目的就是让你不会出错。 举个例子
接着来(这里我只是举例子让大家了解一下,这些代码没有什么实际意义)
假如大家在之后一直在使用obj1和obj2,最后不用的时候,需要释放了,我希望大家这样来释放
这只是一个小例子,你可能感觉不到问题的严重性,如果你做一个项目,在其中有大量这种retain,release的话,你不遵循这种原则,你会死的很惨,没有条理最后你会被搞的很乱,找都找不到。 二、不要随便看到retaincount多就给它释放 很多朋友在学完内存管理后喜欢玩消除,不该释放的他去释放,举个例子
类似还有很多,数组的addobject、addsubview等等很多方法,都是框架自己家retain的,开发者本身retain后release,不必理会它的retaincount。 另外插一句,如果是多人协同开发,这种情况最容易碰到,别人传递一个参数过来,你拿过来retain后使用,使用完毕release,发现retaincount还不是0,于是你继续release,这样你就把你同伴retain的计数给release掉了,当他下次使用的时候发现崩溃了,这种情况会让你的团队浪费无数的时间来找原因。 三、关于属性 属性在.h文件中是这样声明的
我们分析一下他内部的机制 @property (retain) Class* obj;和@synthesize obj;实际上是getter和setter,有retain参数的property,内部代码如下
这个属性定义以后如何使用呢?我们只说赋值(也就是set) self.obj=xxx; [self setObj:xxx]; obj=xxx; 赋值方法有以下几种,其中前两个是相同的,都是调用了setObj:方法同时也就导致了obj的retaincount增加了1,而第三个赋值方法并没有增加retaincount,只是将指针指向了xxx内存地址。 所以大家赋值时可以这样
四、autorelease对象 autorelease对象就是自动释放对象,大家可能会疑惑,能自动释放,我还管理干嘛,我都用自动释放算了,事实不是这样的,自动释放确实好用,但是自己管理内存才能让项目占用更小的资源,跑起来更流畅,大家可以手动管理加autorelease一起来使用,我先讲解一下autorelease对象到底是什么个情况。 首先,告诉大家autorelease对象什么时候才会被释放。 在main函数里有一个autorelease pool,自动释放池,所以在这个自动释放池里的autorelease对象都会在自动释放池结束的时候全部被释放。 大家可能会问了,“难道所有的autorelease对象都是在程序退出的时候才被释放?”,答案当然不是,其实main函数中只是一个程序中众多自动释放池中的一个,每个runloop都会隐性的创建一个自动释放池,啥是一个runloop?每个UIView创建、delegate回调等等都会创建一个自动释放池,记得这个“等等”,意思就是有很多(如果大家想要详细了解runloop,可以去google)。所以大家不用担心autorelease对象不会被释放。 很多系统的方法,比如[NSArray array]、[NSString stringformat]等等返回的对象都是autorelease对象,这些对象是不需要手动释放的,如果手动释放会导致程序崩溃!切记!,原则就是系统中所有没有使用alloc、copy、retain来创建的对象都是autorelease对象,大家千万别手动release! 好了,就说这么多吧,如果有什么错误,希望大家提出,我来改。。。工作太忙,也没啥时间写的更详细!!!望大家见谅! |