0

我正在制作一款由4款迷你游戏组成的iPhone游戏。每个迷你游戏都是一个独立的xib。每场比赛都有自己的菜单和比赛级别。你进入主菜单并选择你想要加载的游戏。如何通过重用单个viewcontroller并处理内存警告来加载xibs?

这就是我目前正在加载每个xib。

MainGameViewController.h

@interface MainGameViewController : UIViewController { 

    UIViewController *currentView; 
    int currentViewId; 
} 

@property (nonatomic, retain) UIViewController *currentView; 
- (void)displayView:(int)intNewView; 
@end 

MainGameViewController.m

@implementation MainGameViewController 

@synthesize currentView; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    currentView = [[LogoScreen alloc] init]; 
    [self.view addSubview:currentView.view]; 
} 

- (void)displayView :(int)intNewView 
{ 
    currentViewId = intNewView; 
    currentView = nil; 
    [currentView release]; 
    switch (intNewView) { 
     case SCR_GAME1: 
      currentView = [[Game1View alloc] init]; 
      break; 
     case SCR_GAME1LEVEL: 
      currentView = [[Game1LevelView alloc] init]; 
      break; 
     case SCR_GAME2: 
      currentView = [[Game2View alloc] init]; 
      break; 
     case SCR_GAME2LEVEL: 
      currentView = [[Game2LevelView alloc] init]; 
      break; 
     case SCR_GAME3: 
      currentView = [[Game3View alloc] init]; 
      break; 
     case SCR_GAME3LEVEL: 
      currentView = [[Game3LevelView alloc] init]; 
      break; 
     case SCR_GAME4: 
      currentView = [[Game4View alloc] init]; 
      break; 
     case SCR_GAME4LEVEL: 
      currentView = [[Game4LevelView alloc] init]; 
      break;  
     default: 
      currentView = [[MainView alloc] init]; 
      break; 
    } 

    [self.view addSubview:currentView.view]; 
} 

- (void)dealloc { 
    [currentView release]; 
    currentView = nil; 

    [super dealloc]; 
} 

@end 

这是水平的启动方式。 Game1View.m

@implementation Game1View 

-init { 
    if (self == [super init]) { 

     MainGameAppDelegate *appdelegate = [[UIApplication sharedApplication] delegate]; 
     isSoundOn = (appdelegate.gvar.soundstate == 1); 
     gamestate = GAME_STATUS_START; 
    } 
    return self; 
} 
... 
... 
- (void)launchgame { 

    MainGameAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 
    appDelegate.gvar.currentId = objectid; 
    [appDelegate displayView:SCR_GAME1LEVEL_GAME]; 

} 

- (void)returnToMain { 
    MainGameAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 
    [appDelegate displayView:SCR_MAIN]; 
} 

@end 

MainGameAppDelegate.m

@implementation MainGameAppDelegate 
@synthesize window; 
@synthesize viewController; 

- (void) displayView:(int)intNewView { 
    [viewController displayView:intNewView]; 
} 
@end 

目前我得到内存警告,当我把意见,然后应用程序崩溃之间的切换。 我的问题是,这是加载这些视图的正确方法吗?我已经发布了我在游戏寿命期间分配的所有内容,而现在我正在为记忆力耗尽而感到茫然。任何帮助将非常感激。

回答

3

你不能正确地释放游戏视图,因为在调用发布之前,你的代码实际上会将currentView设置为零,这意味着你将泄漏每个创建的游戏视图。

- (void)displayView :(int)intNewView 
{ 
    currentViewId = intNewView; 
    currentView = nil; 
    [currentView release]; 
    switch (intNewView) { 

你可能想这样做,而不是:

- (void)displayView :(int)intNewView 
{ 
    currentViewId = intNewView; 
    [currentView release]; 
    currentView = nil; 
    switch (intNewView) { 

而且,你命名你的视图控制器 “查看” s是混乱。考虑给他们更多的描述性名称,如xxxController。

编辑1:

您还需要确保你释放以前的老游戏是从视图层次结构中移除。在释放视图之前先调用[currentView.view removeFromSuperview]以将其删除。

+0

感谢您的快速回复。我认为你的意思是[currentView.view removeFromSuperview];但如果我在[currentView发布]之前添加; 它会导致我的一个xib在释放时有一个EXC_BAD_ACCESS。 – hreaper 2012-03-19 05:15:55

+0

由于您之前已添加子视图,因此必须通过removeFromSuperview删除视图是正常的。尝试启用XCode的僵尸来查看额外版本的发生位置。 – futureelite7 2012-03-19 05:27:04

相关问题