4.单个对象的野指针问题
野指针错误:访问了一块坏的内存(已经被回收的,不可用的内存)。 僵尸对象:所占内存已经被回收的对象,僵尸对象不能再被使用。 默认情况下xcode为了提高编码效率,不会时时检查僵尸对象,打开僵尸对象检测。
空指针:没有指向任何东西的指针,给空指针发送消息不会报错
不能使用[pretain]让僵尸对象起死复生。
5.单个或者多个对象内存管理
为了防止不小心调用了僵尸对象,可以将对象赋值nil(对象的空值)。
retain 和release个数不匹配,导致内存泄露
对象使用的过程中被赋值了nil,导致内存泄露
在函数或者方法中不当的使用retain 或者relase 造成的问题
set方法的内存管理: 1)基本数据类型:直接赋值
-(void)setAge:(int)age{
_age=age;
} 2)OC对象类型
-(void)setCar:(Car*)car{ //1.先判断是不是新传进来的对象 If(car!=_car){ //2对旧对象做一次release [_car release];//若没有旧对象,则没有影响 //3.对新对象做一次retain
_car=[car retain];
} }
6.@calss的使用
作用 可以简单地引用一个类 简单使用 @class Dog; //类的引入 仅仅是告诉编译器: Dog是一个类; 并不会包含Dog这个类的所有内容 具体使用 在.h文件中使用@class引用一个类 在.m文件中使用#import包含这个类的.h文件 通常引用一个类有两种办法: 一种是通过#import方式引入;另一种是通过@class引入;
我们实际开发中尽量在.h头文件中使用@class
#import和@class的区别: 作用上的区别 #import会包含引用类的所有信息(内容), 包括引用类的变量和方法 @class仅仅是告诉编译器有这么一个类, 具体这个类里有什么信息, 完全不知 效率上的区别 如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的头文件稍有改动, 后面引用到这个文件的所有类都需要重新编译一遍, 编译效率非常低。 相对来讲,使用@class方式就不会出现这种问题了
7.autorelease基本使用 自动释放池 (1)在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。 (2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中 (1)iOS5.0以前的创建方式
NSAutoreleasePool *pool= [ [ NSAutoreleasePool alloc] init];
`````````````````
[pool release];//[pool drain];用于mac
(2)iOS5.0以后 @autoreleasepool {//开始代表创建自动释放池 ·······
}//结束代表销毁自动释放池
OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放 考虑这种情况,如果一个方法需要返回一个新建的对象,该对象何时释放? 方法内部是不会写release来释放对象的,因为这样做会将对象立即释放而返回一个空对象; 调用者也不会主动释放该对象的,因为调用者遵循“谁申请,谁释放”的原则。那么这个时候,就发生了内存泄露。
使用autorelease的好处 (1)不需要再关心对象释放的时间 (2)不需要再关心什么时候调用release
基本用法 (1)会将对象放到一个自动释放池中 (2)当自动释放池被销毁时,会对池子里的所有对象做一次release (3)会返回对象本身 (4)调用完autorelease方法后,对象的计数器不受影响(销毁时影响)
autorelease原理: autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease 系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。
对于autorelease pool本身,会在如下两个条件发生时候被释放 1)手动释放Autorelease pool 2)Runloop结束后自动释放 对于autorelease pool内部的对象 在引用计数的retain == 0的时候释放。release和autorelease pool 的drain都会触发retain--事件。
|