27-oc内存管理基本概念

堆和栈

 

栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈(先进后出);

堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由系统回收,分配方式类似于链表。

 


 

内存管理

 所谓内存管理, 就是对内存进行管理, 涉及的操作有:

分配内存 : 比如创建一个对象, 会增加内存占用

清除内存 : 比如销毁一个对象, 能减小内存占用

 


 

内存管理的本质

 

OC对象存放于堆里面

非OC对象一般放在栈里面(栈内存会被系统自动回收)

 


引用计数器和dealloc基本概念

什么是引用计数器

每个OC对象都有自己的引用计数器,它是一个整数,表示有多少人正在用这个对象

引用计数器的作用

 

当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1

当对象的引用计数器为0时,对象占用的内存就会被系统回收

如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除非整个程序已经退出 )

 

操作引用计数器

给对象发送一条retain消息,可以使引用计数器值+1(retain方法返回对象本身

给对象发送一条release消息, 可以使引用计数器值-1

给对象发送retainCount消息, 可以获得当前的引用计数器值

需要注意的是: release并不代表销毁\回收对象, 仅仅是计数器-1

 

dealloc 方法的作用

 

对象即将被销毁时系统会自动给对象发送一条dealloc消息

(因此, 从dealloc方法有没有被调用,就可以判断出对象是否被销毁)

 


 

单个对象内存管理

ARC和MRC

ARC: Automatic(自动) Reference(引用) Counting(计数)

自动引用计数

不需要程序员管理内容,编译器会在适当的地方自动给我们添加release/retain等代码

注意点: OC中的ARC和java中的垃圾回收机制不太一样, java中的垃圾回收是系统干得, 而OC中的ARC是编译器干得

MRC: Manul(手动) Reference(引用) Counting(计数)

什么是手动引用计数?

所有对象的内容都需要我们手动管理, 需要程序员自己编写release/retain等代码

 

重写dealloc方法有什么注意点

重写dealloc方法, [super dealloc]一定要写到所有代码的最后

 


 

多对象内存管理

内存管理的原则

1.谁创建谁release

如果你通过alloc、new、copy或mutableCopy来创建一个对象,那么你必须调用release或autorelease

2.谁retain谁release:

只要你调用了retain,就必须调用一次release

3.总结:

有加就有减,曾经让对象的计数器+1,就必须在最后让对象的计数器-1

 


 

set方法内存管理

"理解set方法内存管理的推导过程,推导过程不需要记,只需要记忆结论就可以"

 

实现set方法内存管理有哪几步

(1)retain需要使用的对象

(2)release之前的对象

(3)只有传入的对象和之前的不同才需要release和retain

- (void)setRoom:(Room *)room

{

    // 1.只有房间不同才需用release和retain

    if (_room != room) {// 0ffe1 != 0ffe1

        

        // 2.将以前的房间释放掉 -1

        [_room release];

        

        /*

         // 3.对房间的引用计数器+1

         [room retain];

         

         //4.将新房间赋值给实例变量

         _room = room;

         */

        // retain不仅仅会对引用计数器+1, 而且还会返回当前对象

        _room = [room retain];

    }

}

 

 


 

dealloc中release对象可以如何简化

- (void)dealloc

{

    NSLog(@"%s", __func__);

    /*

     [_text release];

     _text = nil;

     */

    // 下面这句话相当于调用了set方法

    // 先release旧值, 然后再将新值赋值给属性

    self.text = nil;

    [super dealloc];

}


 

野指针和空指针

什么是僵尸对象?什么是野指针?什么是空指针?如何避免野指针错误?

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

2.野指针指向僵尸对象(不可用内存)的指针给野指针发消息会报EXC_BAD_ACCESS错误

3.空指针没有指向存储空间的指针(里面存的是nil, 也就是0) 给空指针发消息是没有任何反应的

4.为了避免野指针错误的常见办法: 在对象被销毁之后, 将指向对象的指针变为空指针

 

posted @ 2016-03-04 20:05  wc&Home  阅读(257)  评论(0编辑  收藏  举报