• OC内存管理


    管理的范围:任何继承NSObject的对象,对其他的基本数据类型无效。

    当代码快结束时,关于代码块中的所有局部变量会被回收,指向对象的指针也会被回收,此时对象

    没有指针指向他看,但是依然存在于内存中,造成内存泄漏。

    --------------------------------内存泄漏的分类--------------------------------

    常发性:发生内存泄漏的代码会被多次执行到,每次被执行的时候都回导致一块内存泄漏。

    偶发性:只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的,对于特定的环境,偶发性也就变成常发性了。

    一次性:发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,总有一块内存发生泄漏。

    隐式 :概括来说(内存会在程序结束以后释放,但是某些程序一开就是一个月,会造成内存泄漏的堆积,最终耗尽系统所以的内存)。

    ------------------------------对象的基本结构和引用计数------------------------

    OC中每个对象都由自己的引用计数,是一个整数表示对象被引用的次数,就是想着有多少东西在使用这个对象,对象刚被创建时,默认计数器值为1,但计数器的值为0时,对象被销毁。

    判断对象要不要回收的唯一依据就是计数器是否为0,若不为0则存在。

    -------------------------------操作--------------------------------------

    给对象发送消息,进行相应的计数器操作。

    retain消息:使计数器+1,改方法返回对象本身

    release消息:使计数器-1,(并不是代表释放对象本身)

    retainCount:获得对象当前的引用计数器值

    ------------------------------------对象的销毁--------------------------------------------

    当一个对象的引用计数为0时,那么这个对象被销毁,其占有的内存空间被回收。

    *当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这类释放相关的资源,dealloc就像是对象的遗言。一旦重写dealloc方法就必须调用【super dealloc】,并且放在代码块的最后调用(不能直接调用dealloc方法)。

    注意:当对象被回收,其内存空间被回收,那么就不能通过指针再去访问这块内存空间(野指针)

    -------------------------------僵尸对象----------------

    僵尸对象:所占内存已经被回收的对象,僵尸对象不能再被使用。

    空指针:没有指向任何东西的指针(存储的东西是0,null,nil),向空指针发送消息不会报错。

    注意 不能使用[实例对象 retain]让见识对象起死回生。

    内存管理的原则

    1、原则

    只要还有人在使用某一个对象,那么这个对象就不会被回收。

    只要你想使用这个对象,那么久应该让这个对象的引用计数器+1。

    当你不想使用这个对象时,应该让对象的引用计数器-1.

    2、谁创建,谁release

    (1)、如果你通过alloc、new、copy来创建一个对象,那么你就必须调用release或者autorelease

    (2)、不是你创建的就不用你去负责。

    3、谁retain,谁release

    只要你调用了retain,无论这个对象是如何生成的,你都要调用release

    4、总结

    有始有终,有加有减,如果你让某一个对象计数器加1,就应该在其后面-1.

    内存管理代码规范

    -(void)setCar:(Car *)car

    {

    //1.先判断是不是新传进来的对象

    If(car!=_car)

    {

    //2 对旧对象做一次release

    [_car release];//若没有旧对象,则没有影响

    //3.对新对象做一次retain

    _car=[car retain];

    }

    }

    dealloc方法的代码规范

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

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

    -(void)dealloc

    {

    [_car release];

    [super dealloc];

    }

    Autorelease

    1、基本用法:

    a、会将对象放到一个自动释放池中

    b、当自动释放池被销毁时,会对池子里的所有对象做一次release

    c、会返回对象本身

    d、调用完autrelease方法后,对象的计数器不受影响(销毁时影响)

     

    2、好处

    a、不需要在关系对象释放的时间

    b、不需要再关系什么时候调用release

     

    3、使用

    a、占用内存较大的对象,不要随便shiyongautrelease,应该使用release来精确控制

    b、占用内存较小的对象使用autrelease,没有太大的影响。

    4、

    多次使用autrelease

    alloc之后调用了autrele,之后又调用了release

    5、自动释放池

    a、在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的

    b、当一个对象调用autrele时,会将这个对象放到位于栈顶的释放池中

    ======================以下是上课后的添加=============================、

    在手动管理模式中(MRC)中,便利构造器是内部执行了autorelease的 所以由变量构造器方法创建的实例对象是不用在使用完以后release。

    加入容器的对象的引用计数会执行一次retain操作,引用计数加一。

    在对象被容易删除是,对象会执行一次release操作,引用计数减一。

    当容器被销魂时,容器会对所有对象执行一次release操作,所以对象引用计数减一。

    当对象执行一次setter方法时,由于setter内部执行了一次retain操作 ,所以必须在最后对象销毁时,对对象所以的实例变量执行一次release操作

    -(void)setName:(NSString*)name{

        if (_name != name) {

            [_name release];

            _name = [name retain];

        }

    }

    -(NSString*)name{

        return [[_name retain]autorelease];

    }

    - (void)dealloc {//属性的setter方法造成的实例变量的内存泄漏,全部放到dealloc方法内部执行release操作。

        NSLog(@"%@的对象被释放了",self);

        [_name release];

        [_gender release];

        [_mArr release];

        [super dealloc];

    }

     

  • 相关阅读:
    WCF中的序列化[下篇]
    WCF中的序列化[上篇]
    SET TRANSACTION ISOLATION LEVEL 详解
    深入探讨数据仓库建模与ETL的实践技巧
    用SQL语句添加删除修改字段等操作
    WCF数据契约与序列化
    在SQL Server中使用检查约束来验证数据
    C#线程同步的几种方法[转]
    Linq的Join用法
    测试wlm代码高亮插件
  • 原文地址:https://www.cnblogs.com/naizui/p/5067940.html
Copyright © 2020-2023  润新知