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 ] ; }
|