代码是:
if(!spriteInfoBack){
spriteInfoBack = [CCSprite spriteWithFile:@"bg_player.png"];
[spriteInfoBack setAnchorPoint:CGPointMake(0, 1)];
[spriteInfoBack setPosition:CGPointMake(infoLeftX, infoTopY)];
[parent addChild:spriteInfoBack];
}else{
[spriteInfoBack setPosition:CGPointMake(infoLeftX, infoTopY)];
}
崩溃输出是:
[CCSprite setPosition:]: message sent to deallocated instance 0xc59cc70
它位于这一行:
[spriteInfoBack setPosition:CGPointMake(infoLeftX, infoTopY)];
我认为这很奇怪,因为if(!spriteInfoBack)已经检查过实例是否已取消分配。
答案 0 :(得分:1)
您需要保留CCSprite
。类方法spriteWithFile
返回一个自动释放的对象。存储在spriteInfoBack
中的返回值不归您所有。这意味着对象的生命周期直到下一个自动释放池耗尽。从您的代码中可以看出,您正在使用spriteInfoBack
作为延迟初始化然后再使用的内容。您要做的是保留spriteWithFile
的返回值,如下所示:
spriteInfoBack = [[CCSprite spriteWithFile:@"bg_player.png"] retain];
在将来的某个时候,您需要发布spriteInfoBack
。我没有看到该类的其余部分,但如果spriteInfoBack
是一个类的实例变量,那么在dealloc
中这样做是有意义的。
答案 1 :(得分:0)
不,!spriteInfoBack
只是检查nil
的值(即:spriteInfoBlack == nil
),这是不同的(如果你需要说服自己,请在{{1}中记录一些内容部分)。该变量仍然包含一个内存地址,因此崩溃,因为该实例已被释放。
我们无法通过查看实例被解除分配的代码来猜测,因此,一旦您不再需要它,请仔细检查代码,内存管理和/或将else
放入变量中,这确保测试不会失败的方法。
答案 2 :(得分:0)
该实例位于自动释放池中,该池在ui的事件循环的迭代之间耗尽。如果希望对象在自动释放池中存活,则必须自己显式保留/释放对象。即使该对象已被释放(因为您尚未保留它),指针spriteInfoBack
仍会记住该对象的旧地址。