2011-09-17 21 views
0

我正在嘗試寫我的小應用程序,並遇到一些內存管理問題。 起初,我有Game與屬性singleton對象:單身人士的財產記憶管理

//Game.h 
@interface Game : NSObject 

@property (nonatomic, retain) MapBuildingsLayer *mapBuildingsLayer; 

+(Game *) game; 
-(BOOL) addObject:(NSString *) objName At:(CGPoint) pt; 

@end 

其中MapBuildingsLayer只是cocos2d的CCLayer實例

//Game.m 
@implementation Game 
@synthesize mapBuildingsLayer = _mapBuildingsLayer; 

static Game *instance = nil; 

+ (Game *)game { 
    @synchronized(self) { 
     if (instance == nil) { 
      instance = [[Game alloc] init]; 
     } 
    } 
    return instance; 
} 

-(BOOL) addObject:(NSString *)objName At:(CGPoint)pt 
{ 
    if([objName isEqualToString:OBJ_TYPE_PIT]) 
    { 
     if([[Game game].mapBuildingsLayer addPitAt:pt]) //app crashes here 
     { 
      [self toggleConstructionMode]; 
      return YES; 
     } 
    } 
    return NO; 
} 

@end 

MapBuildingsLayer.minit方法我使用GamemapBuildingsLayer屬性來存儲一個參考到我單身人士的這個CCLayer實例(用於將來在其他方法中使用):

//MapBuildingsLayer.m 
@implementation MapBuildingsLayer 

-(id) init 
{ 
    if((self=[super init])) { 
     [Game game].mapBuildingsLayer = self; 
    } 
    return self; 
} 

當我打電話給GameaddObject:objName At:方法時,我的應用程序崩潰EXC_BAD_ACCESS。 我該如何聲明Game單身人士的財產才能在我應用程序的一生中從其他地方使用它?

+0

嘗試啓用NSZombieEnabled,看看有什麼額外的信息,讓你(HTTP://計算器。com/questions/2190227/how-do-i-set-nszombieend-in-xcode-4) – Rengers

+0

@Rengers啓用殭屍不會在調試日誌中添加任何額外的行。 –

+0

mapBuildingLayer在哪裏獲得alloc init'ed? – bryanmac

回答

0

你通常不使用類本身的單身,嘗試改變

 if([[Game game].mapBuildingsLayer addPitAt:pt]) //app crashes here 

 if([self.mapBuildingsLayer addPitAt:pt]) //app crashes here 

你應該使用類外部的[遊戲遊戲]來進入你的類的單例實例並調用它的方法,但是在類的內部,你只需將它稱爲自我就像正常一樣。

通常,如果你打算使用遊戲單身人士,這不是你將如何使用它。試着用一個巨大的狀態機來想象它,創建一個CCScene子類,它將初始化你所有的CCLayer子類並控制它們。然後從狀態機,你可以加載適當的初始化它的場景,並將創建它下面的一切。

在你的applicationDidFinishLaunching方法中,你只需要讓你的單例對象加載你的第一個場景。我真的建議檢查一下Learning Cocos2d Book,因爲它很好地涵蓋了這個單身狀態引擎,我認爲它會清除你所有的問題。

底線是狀態引擎加載加載圖層的場景。

+0

感謝您的諮詢!但是將[遊戲遊戲]改爲[自己]並沒有修復崩潰。 –

+0

保證您的地圖BuildingBuildingsLayer財產目前爲零。 –

+0

是的,這個屬性自然是'nil',然後在初始化'MapBuildingsLayer'後它被設置爲正確的地址(我剛剛通過調試進行了檢查)。我的意思是,我的'MapBuildingsLayer'實例的地址爲'0xAABBCC',例如'[Game game] .mapBuildingsLayer'的值在崩潰時也被設置爲'0xAABBCC'。 –

0

沒有在您的代碼中,我看到您的mapBuildingsLayer初始化。我回到你的實例之前,希望你也應該做

instance.mapBuildingsLayer = [CCLayer alloc] init]; 
+0

當然我有以下幾行: 'MapBuildingsLayer * buildings = [MapBuildingsLayer node];' 在我的代碼中。我的'MapBuildingsLayer'實例被初始化並正常工作(例如捕捉觸摸事件)。 –

+0

@Saran:雖然你是對的,但這可能不是墜機的原因。如果它沒有被初始化,它將是零,發送消息到零將不會導致崩潰。順便說一下,這段代碼應該更多地沿着'instance.mapBuildingsLayer = [[[MapBuildingsLayer alloc] init] autorelease]'的行; – Rengers

0

我認爲你分配mapBuildingsLayer的方式是錯誤的。從MapBuildingsLayer init方法刪除[Game game].mapBuildingsLayer = self,而是添加以下里面Game init()方法:

self.mapBuildingsLayer = [[MapBuildingsLayer alloc] init] autorelease]; 

現在是你單身init方法內初始化,這樣你就可以在任何地方簡單地訪問它[Game game].mapBuildingsLayerGame類之外。如果這不起作用嘗試發佈addPitAt:做什麼。

希望這有助於