zoukankan      html  css  js  c++  java
  • 关于OC的内存管理-01

    1.什么是内存管理?

    大家都知道手机的内存是有限的,app应用的内存也应该是受限制的,随着app应用的使用会导致内存的占用率增大。当内存占用率达到一种程度时。系统会发出内存警告。这时我们须要把一些不用的对象和变量所占用的内存释放掉,也就是说我们须要手动对内存进行管理。

    而我们管理的范围:不论什么继承了NSObject 的对象,对于基本数据类型(比方float、int 、char、struct、enum等)则是无效的。


    2.怎样进行内存管理

    1)每一个OC对象本身就有一个占用4个字节内存的计数器,它存储的是一个整数。表示“当前对象被引用的次数”。当对象一被建立的时候(比如alloc、new、copy)就默觉得1。而计数器的作用就是,当对象的计数器为0时,当前对象就会被系统回收,假设计数器不为0,程序的整个运行过程中,当前对象的内存就一直不回被回收





    2)引用计数器的三种操作

    (1)retain(给对象发送消息一条retain消息)   计数器+1,有返回值,返回的是对象本身

    (2)release (给对象发送消息一条release消息)计数器-1。无返回值。

    (3)retainCount (给对象发送消息一条retainCount消息)获取当前对象的引用计数器值

    3.当对象销毁时系统会自己主动调用dealloc方法,dealloc方法就像临终遗言一样,所以我们一般重写dealloc方法

    而且此方法中,一定要有[super dealloc] ,且一定放在最后面。

    3.如果我们有一个Person 类

    #import <Foundation/Foundation.h >

    @interface Person : NSObject

    {

    {

    int _age ;

    }

    -(void)setAge:(int)age;

    -(int)age;

    }


    #import"Person.h"

    @implementation Person

    {

    -(void)setAge:(int)age{


    _age = age ;

    }



    -(int)age{

    return _age;

    }

    -(void)dealloc{

    NSLog(@"Person 对象被回收");

    [super dealloc]。

    }


    (1)第一种情况

    int main(){

    //当我们一调用alloc时,对象计数器就默觉得1。所以一有alloc ,我们须在后面加上[对象名 release]

    //p-1(当前计数器为1)

    Person *p =[[Person alloc] init];

    //p-2(当前计数器为2)

    [p retain];

    //release表示计数器减1,此时p-1

    [p  release];

    //p-0,这时系统会回收对象p ,运行对象p的dealloc方法

    [p  release];

    return 0;

    }


    (2)另外一种情况


    int main(){

    //当我们一调用alloc时,对象计数器就默觉得1。

    所以一有alloc ,我们须在后面加上[对象名 release]

    //p-1(当前计数器为1)

    Person *p =[[Person alloc] init];

    //p-2(当前计数器为2)

    [p retain];

    //release表示计数器减1,此时p-1

    [p  release];

    //p-0,这时系统会回收对象p 。运行对象p的dealloc方法

    [p  release]。


    //特别。此时系统已把对象p回收,假设我们在这里再多次运行[p release]的话

    //会訪问僵尸对象(已被系统回收的对象,一块不可用的内存)

    //而p这时则叫野指针(指向僵尸对象的指针),会造成坏的訪问即EXC_BAD_ACCESS

    return 0;

    }


    如图:



    (3)第三种情况


    int main(){

    //当我们一调用alloc时,对象计数器就默觉得1。所以一有alloc ,我们须在后面加上[对象名 release]

    //p-1(当前计数器为1)

    Person *p =[[Person alloc] init];

    //p-2(当前计数器为2)

    [p retain];

    //release表示计数器减1,此时p-1

    [p  release];

    //p-0。这时系统会回收对象p ,运行对象p的dealloc方法

    //运行此句的话。假设不打开Enable Zoombie Object 则不会报错

    //假设打开的话。则会出现这种提示错误

    //message send to deallocated instance

    //意思是给已经回收的实例发送消息

    p.age = 10;

    return 0;

    }

    如图:

    (4)第四种情况;

    int main(){

    //当我们一调用alloc时,对象计数器就默觉得1。所以一有alloc ,我们须在后面加上[对象名 release]

    //p-1(当前计数器为1)

    Person *p =[[Person alloc] init];

    //p-2(当前计数器为2)

    [p retain];

    //release表示计数器减1,此时p-1

    [p  release];

    [p  release];

    //结合第三种情况。我们就会这样想,这时计数器本来是0,我们能够运行retain。计数器+1

    //我们不就能够成功运行p.age = 10;了吗 其实,回收的对象是不可能死而复生的。

    //运行的结果如上图。

    //message send to deallocated instance

    //意思是给已经回收的实例发送消息

    p.age = 10;

    return 0;

    }




  • 相关阅读:
    Photoshop 基础七 位图 矢量图 栅格化
    Photoshop 基础六 图层
    Warfare And Logistics UVALive
    Walk Through the Forest UVA
    Airport Express UVA
    Guess UVALive
    Play on Words UVA
    The Necklace UVA
    Food Delivery ZOJ
    Brackets Sequence POJ
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6853336.html
Copyright © 2011-2022 走看看