黑马程序员 (ARC)内存管理总结 ----- 我这是学会了嘛

来源:互联网 发布:ubuntu 14.04 启动器 编辑:程序博客网 时间:2024/06/07 05:57

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、

<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -----------------------


(ARC)内存管理总结 ---- 我这是学会了嘛

这两天学习的是内存管理,看的头好晕,甚至开始怀疑要不要转投java门下,至少不会乱糟糟的叫自己管理什么对象,什么地址。不过一遍学习下来觉得还挺有意思的。我是先看了一遍书,然后才敲的代码,所以刚开始敲代码时,我觉的从内存管理的第一条开始实现。

 * 注意内存管理规则:(1)用alloc、new、copy创建对象后,引用计数器为1,所以要用一次release

                (2)用了多少次retain就要有相应的release与之对应

                (3)设置自动释放的不用自己release,但是自己retain的要用release。

所以我就用alloc、new、copy创建对象来查看它们的retainCount值,结果发现前两个都对,但是用copy的值居然是-1(尼玛书上是不是坑我),我到网上查了查,说什么的深复制和浅复制,弄了半天才算是感觉上明白了(有关深复制和浅复制请看我转载的博客,我觉得说的挺详细的,还有代码呢)。书上说的那个应该是深复制,所以要重写copyWithZone:这个方法。

- (id)copyWithZone:(NSZone *)zone

{

    return [[self class] allocWithZone:zone];

}

这样第一条算是过关了吧!至于第二条我先试了下retain和release的作用打印retainCount值分别+1和-1.内存管理我觉最难是指向同对象不同变量之间的引用而记录引用计算器的数值,不对的话可能导致过早释放对象或没有释放对象。对此我总结出一个规则(嘻嘻,可自豪了,我总结的)就是变量之间的有引用(如a = b,针对OC对象)时,左边的变量作release,右边的变量作retain。为什么呢?我的理解是这样的,引用的过程好比时一个赋值的过程,从左往右,当左边给右边,右边如果原先右内容的话,那么就会被覆盖,所以原先的引用指针就失效,所以的得release(-1),而且必须在这个引用之前。同样得覆盖后的引用指针的引用数就多了一个,所以要retain;至于它放在哪里,根据set方法的内存管理经验,我觉得放到release之前,这个好像可以防止在左右边是同一个对象时内存管理的缺陷。我们以set方法为例。

- (void)setDog:(Dog *)dog

{

    // must dog retian first

    [dogretain];

    [_dog release];

   _dog = dog;

}

穿进去时,假设retainCount值时1,如果retain在release之后且_dog和dog指向同一个对象时,那么这个对象会过早地被释放。所以这样子可以很好解决这个问题。而根据retain和release的次数相对应,则set的方法还没写完(因为你在里面retain了,你有义务把它release),它应该在拥有的对像销毁时,还要做一次release。

- (void)dealloc

{

    [_dog release];

    NSLog(@"Student Object is destory!");

    [superdealloc];

}

还有查看对象是否销毁也是用dealloc这个方法,系统销毁过程会调用这个方法,调用说明这个对象被移出了内存。

* Autorelease和release都是OC中内存管理的操作语法.

  其中release和retain是最早管理内存的语法,通过对类的实例变量中的引用计数器的-1(release)和+1(retain)来控制实现对该对象在内存中是否需要释放。当使

  得它的计数器为0时,对象会被释放。

  Autorelease是一种自动释放内存技术,其实质还是通过release操作,只是它延长 release被调用的时间。其原理是一个叫做释放池(集合),里面存放着一些新创 建的对象,在这个释放池的有效范围内我们不必考虑对象的释放,当一个自动释放池销毁时,该池会对池中所有的对象进行一次release。

 * 区别:

 * 虽然Autorelease可以自动释放,但是当这个池子很复杂时,内存也会出现泄露,而 且想在释放区外使用池中的对象,要用retain保持,最后再用release释放。还有Autorelease

是再释放池释放的时候-1或者释放对象内存,而release是在调用的时候-1或释放对象,从效率上要高一点。

对于OC使用的ARC,它不同于java的垃圾回收机制(gc),ARC的全称是Automatic Reference Counter(自动引用计数),其实还是用retain和release来修改retainCount的值,只不过它不用人去写,系统在编译时自动生成。java的gc是一种运行机制,从这一点也说明它们不是一样的,还有OC有自己gc,但ios不能使用。主要原因是手机资源有限,垃圾回收机制(gc)效率上不高。

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、

<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -----------------------





0 0
原创粉丝点击