前言
大家好,我是milo,上一篇讲到的是关于单个对象的内存管理,看起来是挺容易的,但是涉及到多对象并且对象之间有关联的时候,就会显得比较复杂,所以我们就接下去看看多对象内存的管理。
多对象内存管理
大家应该都知道QQ游戏的斗地主吧,其实多个对象的内存管理跟很多游戏的房间管理差不多。
为了更加具体,下面我们通过代码的方式实现多对象的内存管理。
上代码之前,一定要对下面几条规范心中有数。
1、只要还有人在用某个对象,那么这个对象就不会被回收
2、只要你想用这个对象,就让对象的计数器+1
3、当你不再使用这个对象时,就让对象的计数器-1
4、谁retain谁release :只要你调用了retain,就必须调用一次release
当我们写代码的时候就得按照上面这样的规范去实现。
那么直接看下面见代码:
JJRoom.h(啥也没有。。。)
#import <Foundation/Foundation.h>
@interface JJRoom : NSObject
@end
JJRoom.m
#import "JJRoom.h"
@implementation JJRoom
- (void)dealloc {
NSLog(@"Room 被释放了");
[super dealloc];
}
@end
重写下dealloc 方法,当JJRoom对象回收的时候打印一下。
JJPerson.h
#import <Foundation/Foundation.h>
#import "JJRoom.h"
@interface JJPerson : NSObject {
JJRoom *_room;
}
- (void)setRoom: (JJRoom *)room;
@end
JJPerson有一个JJRoom类型的成员变量,以及自定义的setRoom方法(为了管理成员变量_room的内存)
JJPerson.m
#import "JJPerson.h"
@implementation JJPerson
-(void)setRoom:(JJRoom *)room {
// 初始化的时候_room = nil
if (_room != room ) {// 必须所指的对象不同才能进入,不然就会被释放掉
[_room release];// 把“旧房间“释放掉
_room = [room retain];// “新房间“计数+1,并赋值给成员变量
}
}
-(void)dealloc {
[_room release];// 释放掉成员变量
_room = nil;// 把野指针置空
NSLog(@"Person 被释放了");
[super dealloc];
}
@end
setRoom和dealloc为什么要如此设计,要参照下面的main.m程序进行理解。
main.m(注意:我注释后面例如person 1 则表示person引用次数为1)
#import <Foundation/Foundation.h>
#import "JJPerson.h"
#import "JJRoom.h"
int main(int argc, const char * argv[]) {
JJPerson *person = [[JJPerson alloc] init];// person 1
JJRoom *room = [[JJRoom alloc] init];// room 1
[person setRoom:room];// room 2
[room release];// room 1
JJRoom *room2 = [[JJRoom alloc] init];// room2 1
[person setRoom:room2];// room 0 room2 2
[room2 release];// room2 1
[person release];// person 0 room 0 room2 0
return 0;
}
经过上面那样setRoom和dealloc的设计,我们写代码的时候,就只需要遵行
谁retain谁release :只要你调用了retain,就必须调用一次release
的原则,就可以让我们的程序在满足我们的需求的同时,没有内存泄漏的问题。运行main.m,打印结果:
2018-05-25 23:45:56.467271+0800 多对象内存管理[1979:192423] Room 被释放了
2018-05-25 23:45:56.467498+0800 多对象内存管理[1979:192423] Room 被释放了
2018-05-25 23:45:56.467522+0800 多对象内存管理[1979:192423] Person 被释放了
Program ended with exit code: 0
该释放的都释放了,并且使用中的对象不会释放。
网友评论