【问题标题】:CCSprites in NSMutableArray does not reappear after scene changeNSMutableArray 中的 CCSprites 在场景更改后不会重新出现
【发布时间】:2014-06-26 15:15:39
【问题描述】:

我正在制作一个游戏,并将 CCSprites 放入 NSMutableArray。

当我第一次开始游戏时,精灵出现在屏幕上,一切似乎都正常。 但是当我切换到另一个场景并返回时,屏幕上看不到任何精灵。 下面是初始化 Sprite 的代码。

-(void spritesInit)
    gpsUsersSpritesArray        = [[NSMutableArray alloc]init];
   for (int i = 0 ; i < [userArray count] ; i++){
      playerSprite = [CCSprite spriteWithFile:@"greenspot.png"];
      playerSprite.position = ccp( winSize.width/2, winSize.height/2);
      [self addChild:playerSprite z:5];
      [gpsUsersSpritesArray addObject:playerSprite];
      [playerSprite release];
   }
}

每次调用场景时都会运行上述方法。

我在精灵上运行下面的动作,第一次也很好,但当我离开并返回场景时又不行。精灵似乎已加载,并且代码在有问题的 NSMutableArray 中迭代而没有崩溃,这让我感到困惑。

for (CCSprite *userspot in gpsUsersSpritesArray){
   id fadein  = [CCFadeTo actionWithDuration:0.05 opacity:255];
   id fadeout = [CCFadeTo actionWithDuration:dotFadeTime opacity:30];
   id seq2 = [CCSequence actions:fadein, fadeout,nil ];
   [userspot runAction:seq2];
}

我曾尝试保留 NSMutableArray,但这也无济于事。 我还尝试强制精灵可见并确保精灵的不透明度设置为 255,但仍然没有运气。

我可能忽略了一些东西,但我不这么认为。

谁帮帮我?

非常感谢。

【问题讨论】:

    标签: iphone cocos2d-iphone nsmutablearray ccsprite


    【解决方案1】:

    你不应该释放你的精灵。我认为这会导致崩溃,但它可能会解决您的问题。

    当您使用以下内容创建精灵时:

    CCSprite* mysprite = [CCSprite spriteWithFile:@"whatever.png"];
    

    你永远不应该发布它。在 Objective-C 中编码时,不使用 ARC 时要记住的规则是,您释放自己分配/初始化、新建、保留和复制的对象。您没有在示例代码中这样做。在该方法中,它调用自动释放,使您的释放无效。将对象添加到容器中也是如此。这些容器会自行处理,如果您使用调用自动释放的便捷方法,您不应该代表它们释放或对这些容器之外的保留计数做任何事情,就像您在这种情况下一样。那是无效的。例如,如果您使用 alloc/init 而不是 spriteWithFile 方法,那就没问题了。

    【讨论】:

    • 如果我理解正确:因为我使用了 spriteWithFile 方法,所以 Sprite 在退出场景时会被释放?或者您的意思是在将精灵添加到 NSMutableArray 后不释放它?
    • 两者。您专门调用的方法将自动释放精灵。当它被添加到图层时,图层会保留它。该层也会在时机成熟时释放它,因此您不必担心。容器也是如此。这样想,当你调用那个方法时,精灵是 alloc/init 并且它被设置为自动释放。因此 init 将被释放,而您无需做任何进一步的事情。如果您在 sprite 上调用了 retain,那么您将有责任调用 release 以正确删除保留计数。
    • 换句话说,每个增加保留计数的实例都已经有一个匹配的释放来减少它。通过调用 release,您正在扔掉东西,并且保留计数将在它应该有之前达到 0,这将导致您的精灵在它应该被释放之前被释放。只有在调用了 retain、alloc/init、new 或 copy 时才释放。如果您不专门增加保留计数,则永远不应该减少它。以这种方式设计的方法的主要目的是使整个 alloc/init/autorelease 序列干净漂亮。
    • 要记住的是,除非您调用了retain、alloc/init、new 或copy 自己,否则您没有创建需要调用release 的情况。如果您将该行更改为 mysprite = [[CCSprite alloc] initWithFile@"whatever.png"],那么您的版本将是必需的。 spriteWithFile 已经通过在返回 sprite 之前调用 autorelease 来满足您的需求。
    • 还有最后一件事要说。我找到了解决方案,我在开始场景之前加载了网络数据,因此不需要加载屏幕。我不能在 SO 网站上感谢你,但到底是什么,谢谢你的见解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多