黑马程序员技术交流社区
标题: 单个对象的内存管理 [打印本页]
作者: liminghui 时间: 2015-9-17 18:57
标题: 单个对象的内存管理
内存管理的原则 :
1:如果对象有人在使用,那么就不应该回收。如果你想使用这个对象,就应该让这个对象retain一次。如果你 不想用这个对象了,就应该让这个对象release一次。
2:谁创建 谁release (哪个对象创建了空间,那个对象就release)
3:谁retain 谁release (哪个对象的空间引用计数器retain了,哪个对象就release)
内存管理研究的内容:
1:野指针:定义的指针变量没有初始化或者是指向的空间已经被释放。
2:内存泄露:如果栈区的指针变量已经被释放了,而堆区的空间还没有释放,堆区的空间就被泄露。
单个对象的内存管理(野指针):
1:野指针错误:访问了一块坏的内存(已经被回收的不可用的内存)。
2:僵尸对象:所占内存已经被回收的对象, 僵尸对象不能再被使用。
3:空指针:对象值为空,没有指向任何东西的指针,给空指针发送消息不会报错。
nil: 表示对象的值
NIL:表示类的值
NULL:通用指针(泛型指针)
[NSNull null]: 是一个对象,他用在不能使用nil的场合 (了解即可)
4: 当一个对象的空间被释放了,引用计数器为0,这个对象是僵尸对象,如果再用[对象名 retain]方法是不行的。下面举个例子:
如: Dog *d = [Dog new]; //创建一个对象,他有一个拥有者,引用计数器的值为1
[d release]; //用release方法使计数器减1, 这时的计数器为0,对象的空间被释放。
[d retain]; //对象空间已被释放,对象成为了僵尸对象,这时再retain是不合法的。
如果非要对已释放空间的对象retain,那么看下面的方法 :
如: Dog *d = [Dog new]; //创建一个对象,他有一个拥有者,引用计数器的值为1
[d release]; //用release方法使计数器减1, 这时的计数器为0,对象的空间被释放。
d = nil; // 在上一步对象空间被释放,这时的对象d指向了nil,也就是0,所以下面的retain可以执行
[d retain]; //上一步对象d指向了nil(0),计数器为0,对象有指向不是僵尸对象,多以可以执行这步。
单个对象的内存泄露问题:
情况1:
// 对象创建完成开辟完内存空间后没有release,计数器为1,程序结束后内存还存在没释放
Dog *d = [[Dog alloc] init ];
return 0;
情况2:
// 没有遵守内存管理的原则
Dog *d = [[Dog alloc] init ]; //创建对象 计数器为1
[d retain]; // retain(+1) 计数器为2
[d release]; // release (-1) 计数器为1
return 0; //程序结束时 计数器不为0,内存空间没有释放
情况3:
// 不当的使用了nil
Dog *d = [[Dog alloc] init ]; //创建对象 计数器为1
d = nil; // 把0赋值给了对象d,下面方法不会执行
[d release]; // 这一步就相当于 [nil release]
return 0; //程序结束时 计数器不为0,内存空间没有释放
情况4:
// 在方法中对传入的对象进行了retain
前提: -(void)run{
[d retain] //run方法中retain了一次对象d
}
后续: Dog *d = [[Dog alloc] init ]; //创建对象 计数器为1
[d run] ; //对象d调用方法run 因为run方法中又给对象retain一次 所以计数器为2
[d release]; // 计数器为2,这步只release了一次,计数器为1 内存没被释放。
作者: zhaopengfei 时间: 2015-9-17 21:16
我很想告诉你 我不知奥
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |