黑马程序员——Objective--C基础笔记之内存管理(一)

来源:互联网 发布:加拿大经济数据 编辑:程序博客网 时间:2024/06/06 03:34

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

OC内存管理

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

2.内存泄漏:对象和其他数据类型在系统中的存储空间不一样,其他局部变量主要存放于栈中,而对象存储于堆中,当代码块结束时    这个代码块中涉及的所有局部变量会被回收,指向对象的指针也会被回收,此时对象已经没有指针指向了,但仍然存在于内存          中,造成内存的泄漏。

3.引用计数器:

1).用来保存当前对象有几个东西在使用它(整数)

2).引用计数器是判断对象要不要回收的依据(存在一种例外:对象值为nil时,引用计数为0,但不回收空间)就是计数器是否为0,        若不为0则存在.

3).对引用计数器操作:

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

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

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

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

4.对象的销毁:

当一个对象的引用计数器为0时,该对象会被销毁,占用的内存系统会被回收。对象在被销毁时,系统会自动向对象发送一条dealloc消息,一般会从写dealloc方法,在这里释放相关的资源,重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直接调用dealloc方法),一旦对象被回收了,那么他所占据的存储空间就不再可用,坚持使用会导致程序崩溃(野指针错误)。 

5.注意:

1).对象计数器不为0,存储空间则不会被回收

2).对象一旦创建好,它的引用计数器默认为1,

6.MRC手动内存管理

ARC自动内存管理

注意:创建一个项目,默认的是ARC(自动内存管理)

把ARC自动内存管理换成MRC手动内存管理步骤:



一.手动内存管理

 1.如果想使用这个对象就应该让引用计数器加1,以免空间被回收,如果不想用就让引用计数器为0,释放空间,防止造成内存泄           漏,也就是谁创建的谁release,谁retain谁release。

2.手动内存管理例子:



注意:对象被释放后不能访问它的引用计数器,如果访问的话是野指针访问会造成系统崩溃。

3.重写dealloc方法

1).对象被销毁的时候,会默认调用dealloc方法

2).dealloc方法书写规范,要先释放自己的对象空间,在释放父类的空间

3).注意:dealloc方法不用手动去调用,系统会根据引用计数器的值自动调用



二.单个对象的内存管理(野指针)

1.如果一个对象被释放了,则该对象被称为僵尸对象,僵尸对象不能再使用。

2.野指针就是访问了一块不存在的内存

3.Xcode在默认的情况下在使用僵尸对象是不会报错的,如果想报错的情况下要打开僵尸对象的检测,但一般为提高效率,是不会时时打开僵尸对象检测的。

4.空指针:没有指向任何空间的指针,给空指针发送消息不会报错

    nil:给nil发送任何消息,都没有效果

    Nil:类对象

    NULL:通用指针(泛型指针)

    [NSNull null]是一个对象,他用在不能使用nil的场合。 

5.为避免僵尸对象的使用报错的方法是对象在释放以后,给对象赋值为nil


6.单个对象的内存泄漏问题

1).创建完成之后没有release

 例:Dog *d=[ [Dog  alloc] init ];

        NSLog(@"%lu",d.retainCount);

        引用计数器为1,没有release

2).不当的使用nil

   例:Dog *d=[ [Dog  alloc] init ];

           d=nil;nil赋值给d,实际上是让的指向一个无效的地址

          [d release];相当于让nil 发送release消息,引用计数器不会-1,值为nil的对象retainCount=0

3).在方法中不当的使用retain 和relaese

例:-(void) test:(Dog *)dog{

       //在方法内部修改引用计数器

       [ Dog  retain];

       }

       在main.m里调用

      Dog *d=[ [Dog  alloc] init ];

      [ d test : d];

      [ d release];

注意:此时没有释放空间,应为引用计数器在方法里已经修改了




0 0