我有一个名为 GamePlay 的课程,看起来有点像这样:
@implementation GamePlay
-(id)init{
if((self = [super init])){
self.isAccelerometerEnabled = YES;
//ship defined in header
ship = [Ship shipWithParentNode:self];
CGSize screenSize = [[CCDirector sharedDirector] winSize];
float imageHeight = [ship spriteContentSize].height;
[ship setSpritePosition:CGPointMake(screenSize.width*0.5, imageHeight*0.5)];
}
return self;
}
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
CGPoint pos = [ship spritePosition];
pos.x = acceleration.x * 10;
[ship setSpritePosition:pos];
}
@end
因此,发货类看起来像这样:
@implementation Ship
+(id)shipWithParentNode:(CCNode *)parentNode{
return [[[Ship alloc] initWithParentNode:parentNode] autorelease];
}
-(id)initWithParentNode:(CCNode *)parentNode{
if((self = [super init])){
sprite = [CCSprite spriteWithFile:@"ship.png"];
SpriteLoader *spriteLoader = [SpriteLoader sharedSpriteLoader];
[spriteLoader addTextureAtlas:@"Spites_default.plist"];
CCAnimation *spriteAnimation = [CCAnimation animationWithFrames:[spriteLoader getSpriteFramesWithName:@"ship-" andAmount:[NSNumber numberWithInt:5]] delay:0.08f];
CCAnimate *anim = [CCAnimate actionWithAnimation:spriteAnimation];
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:anim];
[sprite runAction:repeat];
[parentNode addChild:sprite z:0 tag:SHIP];
}
return self;
}
-(void)setSpritePosition:(CGPoint)point{
sprite.position = point;
}
-(CGPoint)spritePosition{
return sprite.position;
}
-(CGSize)spriteContentSize{
return sprite.contentSize;
}
@end
GamePlay 初始化发货并继续修改发货中的CCSprite,并且在模拟器中,一切正常。当在设备上运行它时,我们得到加速度计输入。在加速度计方法中,第一行因程序不再存在而导致程序崩溃。如果我在加速度计方法的第一行查看带有断点的调试器,我会看到以下内容:
self =(GamePlay *)
- > ship =(Ship *)0x004701e0
如果我继续运行该程序,我会收到以下消息: 消息发送到解除分配的实例0x4701e0
但是我不确定为什么它被解除分配......大概是0x004701e0 == 0x4701e0?
非常感谢, 本
答案 0 :(得分:4)
您必须retain
ship
-[GamePlay init]
{以后release
dealloc
{。}}。
答案 1 :(得分:3)
解释问题:
Ole是正确的,因为Ship需要在您发布的代码中保留。我个人认为这里存在设计问题。您的Ship类应该来自CCNode,您应该通过addChild将Ship添加到节点层次结构中。
如果Ship仅从NSObject派生,那么你最终得到的就像是一个“破碎的”节点层次结构:
问题在于Ship类的sprite由Ship类“管理”,但由GamePlay类保留。这意味着您有责任保留非自己的CCNode类。以下是一个更简单,更符合Cocos2D的设计,因为它依赖于Cocos2D来管理整个节点层次结构:
这样你就可以将Ship类作为子类添加到GamePlay类中。 Ship类将其CCSprite实例添加到self(Ship类)。您可以(并且应该)删除shipWithParentNode方法中传递的parentObject。在Cocos2D中将一个节点的实例传递给另一个节点是非常危险的,你可能会想要保留它,这可能会因为循环保留依赖性而导致整个场景泄漏(保留b,b保留a,两者都可以'放手)。
总的来说,这会使您的节点层次结构更深一些,但更容易管理。您可以假设所有对象都从公共基类(CCNode)派生,您可以依赖Cocos2D在正确的时间以正确的顺序释放节点层次结构。