您的位置:首页 > 其它

OC基础-内存管理-引用计数器+set方法

2014-09-30 18:52 267 查看
<1>内存管理--引用计数器

1. 内存中分为五大区域,其中两个是栈和堆。栈存放局部变量,堆存放对象等动态产生的变量,当变量的作用域失效后,栈里的变量系统自动回收,堆不是。

2. 每个对象内部都有自己的引用计数器:表示有多少人在用这个对象(引用器占4个字节)。对象被创建的时候计数器默认是1,当计数器减为0时,对象被回收,只要不是0就不会被回收,除非整个程序退出。

3. 操作对象的计数器

    1> 当使用alloc,new或者copy创建一个对象时,计数器默认是1

     (都是对象方法)

    2> 给对象发送一条retain消息,可以使引用计数器值+1,retain方法返回对象本身

    3> 给对象发送一条release消息,可以使引用计数器值-1

    4> 给对象发送一条retainCount消息,返回当前的引用器值

4. 当对象的引用计数器为0即对象需要被销毁时,系统会自动向对象发送一条dealloc消息(对象的遗言,这比喻。。。。。) ,有时候我们会想在对象被回收之前做一些事情,所以一般都会重写dealloc方法,在这里面释放一些其它的相关资源

5. 对象有没有被回收的依据是系统有没有调用dealloc方法,所以通过重写dealloc就可以检测对象是否被回收

6. 调用dealloc方法一定要调用回super的dealloc:[super dealloc](而且一定要放到最后)

7. 被系统回收的对象是不可再用的,称之为“僵尸对象”,指向僵尸对象(不可用内存)的指针叫做“野指针”(所以不能反复多次’无限‘的release,否则会出现的错误:EXC_BAD_ACCESS(访问一块坏内存,不可用的对象/内存)这叫野指针错误。所以当指针变成野指针时要把这个指针变成空指针:p=nil; 给空指针发送消息不会报错,但是要注意的是-OC里没有空指针操作)

8. retain是有返回值的:对象本身(地址/指针),release没有返回值

<2>内存管理--set方法(涉及到多对象时)

1. 谁创建,谁release,如果你通过alloc,new或者[mutable]copy创建一个对象,那么你就必须要调用release或者autorelease,不是你创建的你就不要管

2. 谁retain,谁release。只要你调用了retain,无论这个对象是如何产生的,你都要调用release

3. 重写!重写!重写!重写方法!----好处多多

4. 总结

    1> 你想使用(占用)某个对象,就应该让该对象的计数器+1(让该对象做一次retain操作)

    2> 你不想再使用(占用)某个对象,就应该让该对象的计数器-1(让该对象做一次release操作)

    3> 谁retain谁release,谁alloc谁release

<3>内存管理--set方法-2(用新对象代替旧对象时,就好比是一个人原来有辆250码的车(旧对象),然后要换一辆3000码的车(新对象))

1. 旧对象与新对象不是同一个对象时:当一个对象换了当前它所使用的对象的时候,就要让 被使用的旧对象release一次。方法是在set方法中让旧对象release(就是在换对象的时候让被换掉的旧对象release一次,被使用的新对象retain一次)

2. 旧对象与新对象是同一个对象时:上面的逻辑就会出现问题,因为换对象的时候,set方法都要release旧对象,但是如果被传入的‘新’对象和‘旧’对象是同一个对象时,‘旧’对象一release,它就可能已经被系统回收了,这时再对‘新’对象进行retain就是非法的. 所以我们在换对象的时候,先要if判断一下:旧对象跟新对象一样就不执行(不换),不一样才会执行(换)

3. 总结:

    <1. 只要调用alloc,就必须有release(或者autorelease)

    <2. set方法的代码规范

        1> 基本数据类型:直接赋值

        - (void)setAge:(int)age

        {

            _age = age;

        }

        2> OC对象类型

        - (void)setCar:(Car *)car

        {

            //1.先判断是不是同一个对象

            if(_car != car)

            {

                //2.旧对象release一次

                [_car release];

                //3.新对象retain一次

                _car = [car retain];

            }

        }

    <3. dealloc方法的代码规范

        1> 一定要[super dealloc],而且要放到最后

        2> 对self(当前)所拥有的其他对象做一次release

        - (void)dealloc

        {

            [_car release];

            [super dealloc];

        }

4. 不管对象是怎么产生的,只要没有使用alloc,就不能用release(如NSString *的对象)

5. 这种情况,release的顺序也有要求,所以很烦,很不合理不友好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐