Raywenderlich教程-简单的iPhone游戏-第2部分



我正在使用iphone游戏教程的第二部分,我对ccTouchesEnded方法的实现感到困惑。这是执行"射击"的地方:玩家(大炮)转向被触摸的方向,然后发射炮弹。我不清楚的部分是:_nextProjectile似乎被释放,而它仍然可以在使用(通过它下面的代码- _nextProjectile runAction)。你能解释一下为什么在这个时候释放物体是安全的吗?

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[_player runAction:
 [CCSequence actions:
  [CCRotateTo actionWithDuration:rotateDuration angle:cocosAngle],
  [CCCallBlock actionWithBlock:^{
     // OK to add now - rotation is finished!
     [self addChild:_nextProjectile];
     [_projectiles addObject:_nextProjectile];

     // Release
     [_nextProjectile release];
     _nextProjectile = nil;
 }],
  nil]];

// Move projectile to actual endpoint
[_nextProjectile runAction:
 [CCSequence actions:
  [CCMoveTo actionWithDuration:realMoveDuration position:realDest],
  [CCCallBlockN actionWithBlock:^(CCNode *node) {
     [_projectiles removeObject:node];
     [node removeFromParentAndCleanup:YES];
 }],
  nil]];

}

ccTouchesEnded:withEvent:之前,您增加了 _next抛射的保留计数:

_nextProjectile = [[CCSprite spriteWithFile:@"projectile2.png"] retain];

因此,在稍后的某个时刻,您必须减少保留计数以防止内存泄漏。换句话说:你有责任释放这个保留。这就是这一行的来源:

[_nextProjectile release];

为什么在那个点释放它是安全的?你在问题中发布的代码片段实际上都是一系列动作中的动作。

[_player runAction:[CCSequence actions:...]];

对对象执行操作会增加对该对象的保留计数。这意味着动作对象本身创建并保存对 _next抛射的另一个引用。动作序列是在动作实际执行之前创建的,因此动作对象已经有了自己对 _next抛射的引用。所以在一个动作中释放它实际上是安全的。他们等待着释放 _next抛射,直到这些行通过:

[self addChild:_nextProjectile];
[_projectiles addObject:_nextProjectile];

在这些行之前发布可能会(我没有看过任何其他代码,除了ccTouchesEnded:withEvent:)导致EXC_BAD_ACCESS运行时错误。

这里有一些关于留存数的更多信息:cocos2d论坛

最新更新