OC加强知识点笔记-内存管理,@class,NSString 内存管理

1.内存管理的范围:所有的OC对象(继承自NSObject类)

2.为什么内存管理只管理OC对象?程序运行时内存分为五大部分:从下往上:代码区,数据区,BSS段,以及堆区,栈区。其中前三个区域的数据,程序启动的时候占用内存区间,无法进行管理。栈区的数据由系统自动管理,不需要进行管理。栈区从高地址向低地址分配,堆区从低地址向高地址分配。堆区主要是OC中的实例对象,内存管理主要是对堆区进行管理,所以内存管理主要进行的OC对象的管理。

3.如何进行内存 管理?通过操作对象的引用计数器。

4.什么是引用计数器?  1)每个对象都有自己的引用计数器。2)它是一个整数(int,占用4个字节)。3)从字面上,可以理解为“对象被引用的次数”。4)也可以理解为:当前有多少个人正在使用这个对象。

5.引用计数器的作用?系统通过“引用计数器”来判断当前对象是否可以被释放。

6.对象的引用计数器的操作方式?   1)retain   使计数器+1  。2)release  使计数器-1。3)retainCount  返回当前计数器的值。当为0的时候无法使用,因为对象已被释放。

7.dealloc 方法。 1)当对象即将被销毁的时候,系统自动给对象发送一条dealloc消息,因此,从dealloc方法有没有被调用,可以判断出对象是否被释放。2)可以重写dealloc方法,并且在重写的最后,要调用父类的dealloc方法,也就是[super dealloc],注意:必须放在最后。3)dealloc方法无法被直接调用,只能系统自动调用。

8.野指针/空指针/僵尸对象。 

  1)僵尸对象:已经被销毁的对象(不能再使用的对象)

  2)野指针:指向僵尸对象的指针。

  3)控制帧:没有指向内存空间的指针。存放的是nil,也就是0.

9.Xcode中有僵尸对象检测机制,开启之后,会防止程序对僵尸对象进行操作。

10.多对象的内存管理:

   -(void) setCar:(Car * ) car {

            _car=car;

}

-(void) drive{ 

          [_car Run];

          NSLog(@" %@在跑", _car.Name);

}

错误实例1):对象已经释放,再次去使用对象的方法。

[ car   release];  //此处释放了car 对象

[ p  drive];   //  此处p 未被释放,但是车已被释放,调用人的方法,造成了野指针car  访问僵尸对象 。

错误实例2):给p.car 设置不同对象造成原对象内存泄漏,原对象没有被释放。

错误实例3):给p.car设置同一对象,造成对象变为僵尸对象,以及本对象的指针成为了野指针。


正确的方法:在set 以及dealloc方法中管理对象的引用计数器:


-(void)  setCar:(Car *) car{

        if(_car!=car)

        {

               [ _car release];

               _car=[car  retain];  

        }

}

-(void) dealloc:{

            [ _car release ];

           [ super  dealloc ] ;

}

11. 苹果官方内存管理的基本原则:

   1) 谁创建谁release ,如果你通过alloc,new 或 copy ,mutableCopy 创建了一个对象,那么必须调用 release 或者autorelease  。

   2)谁retain 谁release,只要你调用了retain ,就必须调用一次release 。


12.@property 的修饰关键字:

   1)控制set 方法的内存管理 :retain :release 旧值,retain 新值(用于OC对象) ,要配合nonatomic 使用。   比如: @property (nonatomic , retain)  car ;

                                                        assign:直接赋值,不做任何内存管理(默认,用于非OC对象类型),不会进行retain。

                                                        copy:release 旧值 ,copy 新值 (一般用于NSString *);

   2)控制是否生成set方法: readwrite: 同时生成get 和set 方法(默认)  ; readonly: 只读,不生成set方法,只生成get方法。

   3)多线程管理:atomic:性能低(默认);nonatomic:性能高,(为IOS系统开发时建议使用,为mac开发可以使用atomic);

   4)控制get和set 方法的名称: setter: 这是set方法的名称,注意要有冒号;getter: 设置get方法的名称,冒号。


13.@class的用法:

    1)为什么要使用@class?  主要是用于解决循环引入的问题,比如A引入B,B引入A,这时用#import 会造成循环以来,使用@class则不会。注意:使用@class之后,要在.m文件中引入 .h文件,比如:A的.m文件中,要引入B.h文件。

    2)和import的区别:主要就是解决循环依赖的问题。


14.内存管理时的循环retain问题。

     比如,A中有一个B 实例对象,B中有一个A实力对象,这时如果把A赋值给B,B赋值给A,如果A,B都是用retain ,会造成程序结束的时候A,B引用计数仍为1,AB无法释放,内存泄漏。

    如果此时A使用retain,B使用assign,则不会造成这种现象,注意:assign的dealloc中不需要release。这是推荐使用方法。另外的方法是:在最后对A或者B 再次进行释放,此处需要注意顺序问题,必须是在程序的最后。


15.NSString的内存管理问题。

    初始化字符串的时候,直接赋值 @"abc",stringWithString ,alloc  initWithString这三种方法中,@"abc"  存放在常量池。重复赋值,不会重新分配内存空间。

     注意:常量区的引用计数是lu的最大值。

    stringWithFormat  alloc  initWithFormat ,存放的地址为堆区。     NSString 不需要我们进行内存管理,Foundation框架会自动帮我们管理。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值