黑马程序员技术交流社区
标题: 疑问:多对象内存管理 [打印本页]
作者: 崔石炫 时间: 2014-9-26 00:29
标题: 疑问:多对象内存管理
看到多对象内存管理的视频,产生了一个疑问,首先看以下代码,就不用老师写的Person和Book了,用QQ堂游戏模拟吧:
- //GameRoom类,表示游戏房间
- @interface GameRoom : NSObject
- {
- int _roomNumber;
- }
- - (void)setRoomNumber:(int) roomNumber;
- - (NSSting *) roomNumber;
- @end
- @implementation GameRoom
- - (void)setRoomNumber:(int) roomNumber
- {
- _ roomNumber = roomNumber;
- }
- - (NSSting *) roomNumber
- {
- return _ roomNumber;
- }
- - (void)dealloc
- {
- NSLog(@” GameRoom对象被释放”);
- [super dealloc];
- }
- @end
- //Player类,表示游戏玩家
- @interface Player : NSObject
- {
- GameRoom *_gameRoom; // 目前所在的游戏房间
- }
- - (void)setGameRoom:(GameRoom*)gameRoom;
- - (GameRoom*)gameRoom;
- @end
- @implementation Player
- - (void)setGameRoom:(GameRoom*)gameRoom
- {
- _ gameRoom = [gameRoom retain];
- }
- - (GameRoom*)gameRoom
- {
- return _ gameRoom;
- }
- - (void)dealloc
- {
- [_ gameRoom release]; // 使引用的GameRoom对象的引用计数器减1
- NSLog(@”Player对象被释放”);
- [super dealloc];
- }
- @end
- //main函数
- int main()
- {
- GameRoom *room = [[GameRoom alloc] init]; //alloc出来的对象引用计数为1
- Player *player = [[Player alloc] init]; //alloc出来的对象引用计数为1
- [player setGameRoom:room]; //room对象引用计数器+1,为2
- [room release]; //room对象引用计数器-1,为1
- room = nil;
- [player release];
- /*player对象引用计数器-1,为0.
- 系统发送dealloc消息,内部向room发送release消息
- room对象引用计数器-1,为0
- */
- player = nil;
- return 0;
- }
复制代码
分析:
以上代码,是没有问题的,程序运行结束时,两个对象都被回收。
现在的问题是:
如果我在main函数中[player release];处重多次复调用player的set方法,
即写多次[player release];,重复设置其_gameRoom属性为room对象,
使room对象引用计数器多次+1,其他代码不变。
最后:
程序运行结束后room对象的引用计数器值还是不为0,导致内存泄露。
作者: wanyiyuan 时间: 2014-9-26 00:44
修改下player类中的 - (void)setGameRoom:(GameRoom*)gameRoom方法
- (void)setGameRoom:(GameRoom*)gameRoom
{
if(_gameRoom != gameRoom){
[ _gameRoom release]; _gameRoom = [gameRoom retain];
}
}
作者: AngleMGG 时间: 2014-9-26 00:53
你是说这样:
[player setGameRoom:room];
[player setGameRoom:room];
[player setGameRoom:room];
其实这样多次重复传入同一个参数是没有意义的,你可以这样:
- - (void)setGameRoom:(GameRoom*)gameRoom
- {
- //先判断传进来的对象是否重复传入
- if(_gameRoom != gameRoom)
- {
- //release旧对象,以便接收新对象
- [_gameRoom release];
-
- //retain新对象
- _ gameRoom = [gameRoom retain];
- }
- }
复制代码
作者: wanyiyuan 时间: 2014-9-26 01:01
set方法不会使计数器加1吧?
作者: 崔石炫 时间: 2014-9-26 02:15
虽说没有意义,但总有人会手抖。:lol
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |