使用cocos2d在init方法中使用EXC_BAD_ACCESS

时间:2012-03-14 10:31:40

标签: objective-c inheritance cocos2d-iphone initialization exc-bad-access

好的伙计们,我有一个让我感到困惑的人。我已经做了一些寻找答案,但我发现的任何事情都没有解决。如果我错过了相关的答案,请接受我的道歉,并请我指出正确的方向。那说......

我的问题是一个exc_bad_access错误,我知道这通常是由于尝试对已经释放内存的对象做了一些事情。但是,我的困惑来自这样一个事实:当我尝试设置任何类值时,我会创建一个层的实例(通过init方法),然后抛出有问题的错误。精灵是超类的成员......超级类继承自CCLayer。为什么我说我正在尝试访问当我的图层显然刚创建并为其分配内存时已释放的内存?有没有解决方案摆脱此错误消息?也许在目标c中存在一些我不知道的遗传问题?

以下是我尝试创建的图层中的相关方法:

+(CCScene *) scene
{
    CCScene *scene = [CCScene node];

    //note that i allocate and initialize the object just like any other object
    //I've also tried retain here
    MainGameLayer *layer = [[MainGameLayer alloc] init];
    layer = [MainGameLayer node];

    HUD *hudLayer = [[HUD alloc] initWithLayer:layer];
    [scene addChild:hudLayer z:1];

    [scene addChild:layer];

    return scene;
}

-(id) init {
    //will call the init method shown below
    if (self=[super init]) {

        //program crashes right here on this line with exc_bad_access 
        centerBackground = [CCSprite spriteWithFile:@"background.png"];
        centerBackground.position = ccp(240, 160);
        [self addChild:centerBackground];

        eastBackground = [CCSprite spriteWithFile:@"background.png"];
        eastBackground.position = ccp(752, 160);
        [self addChild:eastBackground];

         westBackground = [CCSprite spriteWithFile:@"background.png"];
         westBackground.position = ccp(-272, 160);
         [self addChild:westBackground];

         northBackground = [CCSprite spriteWithFile:@"background.png"];
         northBackground.position = ccp(240, 672);
         [self addChild:northBackground];

         southBackground = [CCSprite spriteWithFile:@"background.png"];
         southBackground.position = ccp(240, -352);
         [self addChild:southBackground];
    }
    return self   
}

以下是我的图层继承的超类的接口:

@interface GamePlayLayer : CCLayer <UIAccelerometerDelegate> {
    UIAccelerometer *accelerometer;
    float xAccelerationFactor;
    float yAccelerationFactor;
    float zAccelerationFactor;
    CCSprite *centerBackground;
    CCSprite *eastBackground;
    CCSprite *westBackground;
    CCSprite *southBackground;
    CCSprite *northBackground;
    CCSprite *southWestBackground;
    CCSprite *southEastBackground;
    CCSprite *northWestBackground;
    CCSprite *northEastBackground;
}

@property (nonatomic, retain) UIAccelerometer *accelerometer;
@property float xAccelerationFactor;
@property float yAccelerationFactor;
@property float zAccelerationFactor;

@end

...和超类的init方法

- (id) init {
    //note that this init finishes with no problems
    xAccelerationFactor = 0;
    yAccelerationFactor = 0;
    zAccelerationFactor = 0;

    self.accelerometer = [UIAccelerometer sharedAccelerometer];
    self.accelerometer.updateInterval = .1;
    self.accelerometer.delegate = self;
}

非常感谢任何帮助或一般建议。非常感谢![/ p>

2 个答案:

答案 0 :(得分:0)

您将MainGameLayer *layer设置两次。不需要第一个alloc并且因为它没有被释放而韭菜内存。

改变这个:

MainGameLayer *layer = [[MainGameLayer alloc] init];
layer = [MainGameLayer node];

到此:

MainGameLayer *layer = [MainGameLayer node];

答案 1 :(得分:0)

此代码应吐出警告“控制到达非空函数的结尾”:

- (id) init {
    //note that this init finishes with no problems
    xAccelerationFactor = 0;
    yAccelerationFactor = 0;
    zAccelerationFactor = 0;

    self.accelerometer = [UIAccelerometer sharedAccelerometer];
    self.accelerometer.updateInterval = .1;
    self.accelerometer.delegate = self;
}

您声明init返回类型id的值。什么也没有回报。然后你不使用任何东西并将其分配到self这里:

 if (self=[super init]) {

在最好的情况下,非返回值只是nil。但那不会崩溃。所以我想发生了两件事之一:

  • 自我保持未初始化的随机值。
  • self使用堆栈的返回值进行初始化,但由于您实际上从未返回过值,因此返回值只是一个随机值。

长话短说:永远不要忽视警告,除非你知道你在做什么。在构建设置中启用“将警告视为错误”,这可能是一个非常有针对性的纪律措施。 :)