由于Xcode6.0.1中默认开启ARC(Automatic Reference Counting  自动引用计数器),在学习ARC之前,我们需要做以下两步:

(1)要想手动管理内存,调用retain 、 release等方法,需要关闭ARC:

iOS _ 引用计数 引用计数器_iOS _ 引用计数

 

(2)默认情况下,Xcode是不会管僵尸对象的,使用一块被释放的内存也不会报错。为了方便调试,应该开启僵尸对象监控

  第1步:

    

iOS _ 引用计数 引用计数器_指针变量_02

  第2步:

    

iOS _ 引用计数 引用计数器_野指针_03

  第3步:

    

iOS _ 引用计数 引用计数器_野指针_04

  iOS程序中需要程序不断处于运行状态,因此iOS程序的main函数是一个死循环,除了用户控制退出程序可以释放内存,程序员还可以通过代码来释放(调用方法)。

一、基本使用

(1)当使用alloc创建一个新对象时,新对象的计数器值默认是1

iOS _ 引用计数 引用计数器_指针变量_05

 

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

iOS _ 引用计数 引用计数器_iOS _ 引用计数_06

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

iOS _ 引用计数 引用计数器_指针变量_07

(4)验证对象内存是否被回收

super的dealloc 必须调用,而且要放在最后面。

iOS _ 引用计数 引用计数器_空指针_08

 

二、野指针、空指针

1、野指针:指向僵尸对象(不可用内存)的指针。

iOS _ 引用计数 引用计数器_空指针_09

iOS _ 引用计数 引用计数器_空指针_10

 

分析:

1> 当执行完第8行代码,计数器值变为0。Person对象被回收,它所占用的内存变为不可用,这时Person对象就成为僵尸对象。

2> 虽然Person对象被回收,但是指针变量p存储的地址值没有清空,它还是指向Person对象原来所占用的内存空间,而这个空间此刻已经变为不可用内存,这个时候,指针变量p就成为野指针。

(1)如果对野指针继续调用release方法,就会出现野指针错误:

EXC_BAD_ACCESS 访问了一块坏的内存(已经被回收、已经不可用的内存)  也称为野指针错误。

iOS _ 引用计数 引用计数器_指针变量_11

(2)调用野指针的方法,出现野指针错误

-[Person setAge:]: message sent to deallocated instance 0x100203210

表示发送一条 - setAge:

iOS _ 引用计数 引用计数器_指针变量_12

 

(3) 对一个僵尸对象使用retain方法

retain方法使其变为可用。即  对象不能死而复生。因为会出现野指针错误:

-[Person retain]: message sent to deallocated instance 0x100203210

给已经被释放的对象发送 - retain消息。

iOS _ 引用计数 引用计数器_空指针_13

2、空指针

空指针:没有指向任何东西的指针(不指向任何对象)。

上例中,当计数器值为0时,对象被回收,但是指针变量p还保存着对象的地址,指向一块不可用的内存,称为野指针。

为了保证指针的干净,我们可以清空指针存储的内容: 把nil赋值给指针变量

iOS _ 引用计数 引用计数器_野指针_14

注意:OC中没有空指针错误,给空指针调用方法不会报错:

iOS _ 引用计数 引用计数器_野指针_15

三、引用计数器总结

1、方法的使用

(1)retain : 计数器 +1,会返回对象本身。

(2)release : 计数器 -1,没有返回值。

(3)retainCount : 获取当前的计数器值。

(4)dealloc:对象被销毁时被调用,一般会重写dealloc方法。

  1> 当一个对象要被回收的时候,就会调用。

一定要调用[super dealloc],这句调用要写在最后面。

2、理解概念

(1)僵尸对象:所占用内存已经被回收的对象,僵尸对象不能再使用。

(2)野指针: 指向僵尸对象(不可用内存)的指针。

(3)空指针: 没有指向任何东西的指针(存储的东西是nil、null、0),给空指针发送消息不会报错,OC中没有空指针错误。

 

人生之路,不忘初心,勿忘始终!