0

好吧,我有一個讓我困惑的東西。我已經做了一些尋找答案,但沒有發現我已經清除了任何東西。如果我錯過了一個有關的答案,請接受我的道歉,並請指出我正確的方向。這就是說...EXC_BAD_ACCESS在init方法裏用cocos2d

我的問題是一個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; 
} 

任何幫助或一般建議,非常感謝。提前感謝!

+0

請給我們一個例子,它在哪裏崩潰請。 – JeremyP 2012-03-14 11:16:50

+0

Doh!我弄明白了,坦率地說我很尷尬。問題是我不會從超類的init方法返回自我。添加該行解決了問題。謝謝您的幫助! – Wynn 2012-03-14 11:41:20

+0

哦,是的,應該看到。你需要用這個答案創建一個答案,並接受它。 – JeremyP 2012-03-14 11:42:50

回答

0

此代碼應吐出一個警告 「控制達到的非void函數結束」:

- (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用堆棧中的返回值進行初始化,但由於您從未真正返回過一個值,所以返回值只是一個隨機值。

長話短說:永遠不要忽視警告,除非你知道你在做什麼。打開「構建設置」中的「將警告視爲錯誤」,這可能是頗具指導性的紀律措施。 :)

0

您設置了MainGameLayer *layer兩次。第一個分配是不需要的,因爲它沒有被釋放,所以韭菜回憶。

更改此:

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

這樣:

MainGameLayer *layer = [MainGameLayer node]; 
+0

我明白了爲什麼我應該做出這種改變,因爲內存泄漏,並因爲init被調用兩次,但不幸的是,這似乎並沒有解決我的問題(仍然在同一個地方得到相同的錯誤)。 – Wynn 2012-03-14 10:57:20