• 关于内存管理/set/get方法


    MRC状态下

    1 任何继承NSObject的对象,存放于堆控件中,都需要手动管理内存 。
    2 基本数据类型放到栈中,对象放到堆空间中,内存是有系统管理的。(intfloatenumstruct)

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

    上图:[p release];

    Person 对象引用计数器为0,手动释放内存,对象被系统回收。

    此时:

    僵尸对象:当前Person对象成为僵尸对象(对象的内存空间被系统回收,且无法再继续使用)

    野指针:指针p被成为野指针(指向僵尸对象的指针) 给野指针发送消息 会 报错

    当 p = nil; p =0; p = NULL;

    空指针 此时的p 为空指针(没指向任何东西的指针) 给空指针发送消息 不会 报错

    检测僵尸对象( 僵尸对象检测 stop右-》Edit Scheme-》Diagncatics-》 Objective-C-》勾选Enable zomble objects)



     Set方法的内存管理

     set方法的内存管理分为两块

    1 set方法中的 release旧值 retain新值

    2 dealloc 的release 新值(呼应set方法中的retain新值)。

    @property

    在MRC状态下

    1:例如 @property Book *book;

    意义:实现了book的get set方法,生成了_book 且(set方法中无release旧值及retain新值操作仅仅是简单的赋值)

    2:例如 @property(assign) int age;

    意义:实现了book的get set方法,生成了_book 且(set方法中无release旧值及retain新值操作仅仅是简单的赋值),其实不写assign也可以,即为直接赋值。

    3:例如 @property(retain) Book *book;

    意义:实现了book的get set方法,生成了_book 且(set方法中生成了release旧值及retain新值操作,内存管理代码生成)但是dealloc中的新值release仍需手动释放。

    4:例如 @property(copy) Book *book;
    意义:实现了book的get set方法,生成了_book 且(set方法中生成了release旧值及retain新值操作,内存管理代码生成)但是dealloc中的新值release仍需手动释放 雷同retain

    5:例如 @property(readonly/readwrite)Book *book;
    意义:前者 生成book的get方法 生成_book, 后者实现了book的get set方法,生成了_book

    6:蛋疼的改名 给变set、get方法名

    //重命名 set方法setTest方法名更改为setAbc get方法test更改为bcd 仅仅是改名字 生成的_test变量不变
    @property (nonatomic, assign,setter= setAbc:,getter = bcd) int test;
    
    -------M --------
    //1 如果同时重写了 set get方法则_test变量消失。。。已测试
    //1 如果直重写了 set get方法其中之一 _test不变
    -(void)setAbc:(int)test
    {
        _test = test;
    
    }
    //- (int)bcd
    //{
    //    return _test;
    //}

    PS:所以MRC中,property需要配合dealloc使用

     



    //property 变量 意味着:生成带下划线的成员变量,自动生成setter/getter方法.

    //Setter方法是直接赋值(无release旧值 retain新值操作)
    //getter方法是返回


    //如果两个方法你都手动实现(重写set/get),意味着覆盖原来生成的get/set方法 及下划线成员变量(已测试)。


    //如果只实现get/set其中的一个方法,剩下的原方法不会被覆盖还是会生成带下划线的成员变量,


    //@property(retain) Book *book;

    参数retain:意味着 release旧值 retain新值
    被retain的对象,一定要在dealloc中release下

    //@property(assign) int age;
    参数assign:意味着 直接赋值(默认就是直接赋值)

    //@property(copy) Book *book;
    参数copy:意味着 release旧值 retain新值


    //@property(readonly/readwrite)
    只生成get方法/set方法

    PS:所以MRC中,property需要配合dealloc使用

    ---------单个对象的内存管理---------

    每个对象给引用计数器分配四个字节的存储空间,当对象的引用计数器为零时,系统自动回收对象
    对象 retain 计数器加1


    对象 alloc retain copy 引用计数器加1

    dealloc 对象被销毁,系统会自动给对象发送一条dealloc方法
    dealloc里面写东西一定最后调用[super dealloc];

    ios的main函数是个死循环

    ---------多个对象之间的内存管理---------

    oc对象管理内存

    内存管理

    1 任何继承NSObject的对象,都需要管理内存
    2 基本数据类型放到栈中,对象放到堆空间中
    3 oc对象 nil指针 release 不报错
    4 僵尸对象检测 stop右-》Edit Scheme-》Diagncatics-》 Objective-C-》勾选Enable zomble objects

    ---------单个对象的内存管理---------

    每个对象给引用计数器分配四个字节的存储空间,当对象的引用计数器为零时,系统自动回收对象
    对象 retain 计数器加1


    对象 alloc retain copy 引用计数器加1

    dealloc 对象被销毁,系统会自动给对象发送一条dealloc方法
    dealloc里面写东西一定最后调用[super dealloc];

    ios的main函数是个死循环

    ---------多个对象之间的内存管理---------

    oc对象管理内存


    1 Set方法:将传进来的对象,给类的_成员变量,赋值。
    2 Get方法:返回_成员变量.

    3 关于set方法的内存管理流程(以人书为例):
    set方法,将传进来的book给_book赋值,先要对book 做一次retain计数器加一
    _book=[book retain];

    person类被销毁时,会调用dealloc方法,所有在这里要对_book最一次release,

    4 set方法的标准写法(非常重要)

    - (void)setCar:(Car *)car

    {

    if (car!=_car) { // 1
    [_car release];// 2
    _car=[car retain]; // 3

    }
    }
    注释:set方法,提供方法以便修改一个类下划线成员变量的值,
    1 正常情况下,只修改一次成员变量的值,只写3即可(将传入的对象retain下在赋值),
    2 如果再次修改成员变量值,则需要对之前传入的对象做一次release,即当前对象_car。
    3 为了严谨,需加判断,现在传入的对象非当前对象。

    5 - (Car *)car

    {

    return car;

    }

    6 - (void)dealloc
    {

    // 1:对当前所拥有的所有对象做一次relase方法

    [_car release];

    [super dealloc];
    }

    在MRC中 4,5,6是setter getter的标准写法
    // 2:最后调用



    //循环引用
    @class:仅仅告诉编译器这是一个类.就可以引用一个类
    一方包含头文件 把两边头文件中的#import换成@class即可
    实现文件中#import.

    //解决循环引用问题:
    两端 一边用@property(retain) dealloc继续release
    一边用@property(assign) dealloc无需release


    //autorelease
    //@autoreleasepool

    当对象 调用autorelease方法时,系统会将对象放到释放池中,对对象的计数器无任何影响

    //@autoreleasepool PS:ios5.0之后的

    //在ios5.0之前 需要创建一个自动释放池对象,在销毁!~
    @autoreleasepool
    {//开启释放池

    }
    //结束释放池(池中所有对象做一次release操作)

    自动释放池是存在系统的栈中的(这和局部变量的栈不是一个),栈的特点是先进后出

    自动释放池是存在系统的栈中的(这和局部变量的栈不是一个),栈的特点是先进后出

    参考资料:http://www.cnblogs.com/appzhang/p/3588169.html

    http://blog.csdn.net/q199109106q/article/details/8565017

  • 相关阅读:
    vsprintf解析
    带grub的软盘镜像制作
    SunnyOS准备4
    SunnyOS准备3
    SunnyOS准备1
    汇编第七日
    汇编第六日
    解决k8s集群中mount volume失败的问题
    更新k8s集群的证书
    为k8s集群配置自定义告警
  • 原文地址:https://www.cnblogs.com/ly1973/p/3705731.html
Copyright © 2020-2023  润新知