【问题标题】:Objective-c Array not deallocating objects when removing删除时Objective-c数组不释放对象
【发布时间】:2012-05-04 18:58:32
【问题描述】:
// AClass.m
// init
enemyBullets = [[NSMutableArray alloc] initWithCapacity:0];
enemy1 = [[Enemy alloc] initWithBullets:enemyBullets];

// At some point
NSMutableArray *bulletsToDelete = [NSMutableArray array];
for(BulletEnemy *thisBullet in enemyBullets)
{
    // If I have to delete
    [bulletsToDelete addObject: thisBullet];
}
[enemyBullets removeObjectsInArray:bulletsToDelete];

//dealloc method
[enemyBullets release];
[enemy1 release];

现在在 Enemy 内部某个时间点我会执行以下操作:

// Enemy.m
- (id)initWithBullets:(NSMutableArray*) _bullets{
     // Enemybullets is a var of Enemy
     enemyBullets = _bullets;
}

// At some point...
myBullet = [[BulletEnemy alloc] init];
[enemyBullets addObject:myBullet];
[myBullet release];

问题是当我在 Aclass 执行以下操作时:

[enemyBullets removeObjectsInArray:bulletsToDelete];

BulletEnemy 中的 dealloc 方法没有被调用,因为保留计数不为 0。为什么?但是如果我释放 ACLass(它会释放enemyBullets),那么我的子弹就会被释放。

【问题讨论】:

  • 为什么Enemy 不保留EnemyBullets 数组?您似乎没有遵循标准的内存管理实践。
  • 您的“在某些时候”位非常奇怪。如果您想有选择地从数组中删除内容,请构建一个包含您不想要的对象索引的NSMutableIndexSet,然后使用-removeObjectsAtIndexes:。或者只是做一个反向枚举并立即从数组中删除对象。
  • @trojanfoe,我必须保留它吗? enemyBullets = [_bullets retain] 澄清一下,当我释放 Aclass 时会调用 dealloc,它释放了enemyBullets。
  • 首先我想说[Enemy init] 应该创建子弹数组,然后您可以将readonly 正确添加到Enemy 类中,以便其他对象可以访问该数组并添加到它。我不清楚为什么敌人拥有子弹。它们不是同胞对象都出现在屏幕上吗?
  • Enemy 拥有enemybullets,因此我可以创建 BulletEnemy 并将其添加到数组中。管理enemyBullets的是AClass。

标签: objective-c


【解决方案1】:

让敌人拥有敌人的子弹。并使用 reverseObjectEnumerator

// AClass.m
// init
enemy1 = [[Enemy alloc] init];

// At some point
for(BulletEnemy *thisBullet in enemy1.enemyBullets.reverseObjectEnumerator)
{
    // If I have to delete
    [enemy1.enemyBullets removeObject:thisBullet];
}

//dealloc method
[enemy1 release];

//Enemy.h
@property (retain) NSMutableArray* enemyBullets;


// Enemy.m
@synthesize enemyBullets = _enemyBullets;

- (id)init{
     // Enemybullets is a var of Enemy
     _enemyBullets = [[NSMutableArray alloc] init];
}

// At some point...
myBullet = [[BulletEnemy alloc] init];
[enemyBullets addObject:myBullet];
[myBullet release];

-(void) dealloc{
    [_enemyBullets release];
}

【讨论】:

  • 什么?不,我不会在任何地方保留 myBullet。
  • 改成这样会发生同样的情况吗? for(BulletEnemy *thisBullet inenemyBullets.reverseObjectEnumerator) { [enemyBullets removeObject: thisBullet]; }
  • 或者您是否在任何时候都为 myBullet 使用积木?可以按块保留。
  • 不,没有块。尝试使用 reverseObjectEnumerator,但当我从enemyBullets 中移除子弹时,它仍然没有释放子弹。
  • 代码显示 AClass 拥有enemyBullets 因为它不释放并且在 dealloc 时释放。
【解决方案2】:

显然,我用保留属性分配了一些东西,这使得对象 +1 因此不会释放。只需更改要分配的属性即可。

【讨论】:

    猜你喜欢
    • 2011-01-26
    • 2010-12-22
    • 1970-01-01
    • 2012-08-27
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多