最简单的IOS - 内存管理 四 单个对象和多个对象的内存管理(MRC中)

本文详细解析了内存泄漏的概念及预防措施,并针对Objective-C中属性的管理提供了具体指南,包括@Setter方法的最佳实践、@property的各种参数及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.内存泄露

    指的是1个对象没有被及时的回收.在该回收的时候而没有被回收

    一直驻留在内存中,直到程序结束的时候才回收.

 

 

2.单个对象的内存泄露的情况

     

     1).有对象的创建,而没有对应的relase

 

     2). retain的次数和relase的次数不匹配.

 

     3).在不适当的时候,为指针赋值为nil(指针指向的内存空间未被回收)。

 

     4).在方法中为传入的对象进行不适当的retain。

 

 

3.如何保证单个对象可以被回收

 

     1).有对象的创建就必须要匹配1relase

 

     2). retain次数和release次数一定要匹配.

 

     3).只有在指针称为野指针的时候才赋值为nil

 

     4).在方法中布不要随意的为传入的对象retain.


4.当属性是1OC对象的时候. setter方法的写法

 

    将传进来的对象赋值给当前对象的属性,代表传入的对象多了1个人使用,所以我们应该先为这个传入的对象发送1retain消息再赋值.

 

    当当前对象销毁的时候.代表属性指向的对象少1个人使用.就应该在deallocrelase

 

 

    代码写法:

 

     - (void)setCar:(Car *)car

     {

        _car = [car retain];

     }

 

 

     - (void)dealloc

     {

        [_car release];

        [super dealloc];

     }

 

 

 

5.当属性是1OC对象的时候,setter方法照着上面那样写,其实还是有Bug.
  当为对象的这个属性多次赋值的时候.就会发生内存泄露.
  发生泄露的原因:当为属性赋值的时候,代表旧对象少1个人用.新对象多1个人使用.
  应该relase旧的 retain新的

 

 

     - (void)setCar:(Car *)car

     {

         [_car release];

         _car = [car retain];

     }



6. 在MRC的开发模式下.1个类的属性如果是1个OC对象类型的.那么这个属性的setter方法就应该按照下面的格式写.

    
     - (void)setCar:(Car *)car
     {
         if(_car != car)
         {
            [_car release];
            _car = [car retain];
         }
     }
 
     还要重写dealloc方法.
     - (void)dealloc
     {
        [_car release];
        [super delloc];
     }
 
     如果属性的类型不是OC对象类型的.不需要像上面那样写. 还是像之前那样写就OK了.
 
 

7. @property

 
     1). 作用
         a. 自动生成私有属性.
         b. 自动生成这个属性的getter setter方法的声明.
         c. 自动生成这个属性的getter setter方法的实现.
 
         特别播报:
         生成的setter方法的实现中,无论是什么类型的,都是直接赋值.
 
 
 

8. @property参数.

 
     1). @property可以带参数的.
         @property(参数1,参数2,参数3......)数据类型 名称;
 
 
     2). 介绍一下@property的四组参数.
 
         a. 与多线程相关的两个参数.
            atomic、nonatomic.
 
         b. 与生成的setter方法的实现相关的参数.
            assign、retain.
 
         c. 与生成只读、读写相关的参数       
            readonly readwrite
 
         d. 是与生成的getter setter方法名字相关的参数.
            getter  setter
 
 
 

9. 介绍与多线程相关的参数.

 
     atomic: 默认值. 如果写atomic,这个时候生成的setter方法的代码就会被加上一把线程安全锁.
             特点: 安全、效率低下.
     nonatomic: 如果写nonatomic 这个时候生成的setter方法的代码就不会加线程安全锁.
             特点: 不安全,但是效率高.
 
     建议: 要效率. 选择使用nonatomic  在没有讲解多线程的知识以前 统统使用nonatomic
 
 
 

10. 与生成的setter方法的实现相关的参数.

 
     assign: 默认值 生成的setter方法的实现就是直接赋值.
 
     retain: 生成的setter方法的实现就是标准的MRC内存管理代码.
             也就是. 先判断新旧对象是否为同1个对象 如果不是 release旧的   retain新的.

 
     当属性的类型是OC对象类型的时候,那么就使用retain
     当属性的类型是非OC对象的时候,使用assign.
 
     千万注意:
     retain参数.只是生成标准的setter方法为标准的MRC内存管理代码 不会自动的再dealloc中生成relase的代码.
     所以, 我们还要自己手动的在dealloc中release
 
 
 

11. 与生成只读、读写的封装.

 
     readwrite: 默认值.代表同时生成getter setter
     readonly: 只会生成getter 不会生成setter
  
 
 

12. 生成getter、setter方法名称相关的参数.

 
     默认情况下.@property生成的getter setter方法的名字都是最标准的名字.
     其实我们可以通过参数来指定@property生成的方法的名字.
 
     getter = getter方法名字 用来指定@property生成的getter方法的名字.
     setter = setter方法名字.用来指定@property生成的setter方法的名字. 注意.setter方法是带参数的 所以要加1个冒号.
 
     
     记住:如果使用getter setter修改了生成的方法的名字.
          在使用点语法的时候.编译器会转换为调用修改后的名字的代码.
 
     修改生成的getter setter方法名字. 因为默认情况下生成的方法的名字已经是最标准的名字了.
     所以.一般情况下不要去改.
 
 
     1). 无论什么情况都不要改setter方法的名字. 因为默认情况下生成的名字就已经是最标准的了.
     2). 什么时候修改getter方法的名字.当属性的类型是1个BOOL类型的时候.就修改这个getter的名字以is开头 提高代码的阅读性.
 
 
 
 ------总结-------
 
 1. 与多线程相关的参数: 用nonatomic
 2. 与生成的setter方法实现相关的参数
    属性的类型是OC对象的时候 使用retain
    属性的类型是非OC对象的时候 使用assign
 
 3. 只读 读写.  
    如果你希望生成的封装是只读封装  那么就使用readonly
    如果希望读写封装 readwrite
 
 4.  1). 无论什么情况都不要改setter方法的名字. 因为默认情况下生成的名字就已经是最标准的了.
     2). 什么时候修改getter方法的名字.当属性的类型是1个BOOL类型的时候.就修改这个getter的名字以is开头 提高代码的阅读性.
 
 ------使用参数注意-----
 1. 同1组参数只能使用1个.
    getter setter可以同时使用.
 
 2. 参数的顺序可以随意.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值