【问题标题】:Creating multiple class instances on the fly即时创建多个类实例
【发布时间】:2009-07-24 18:00:49
【问题描述】:

我的问题涉及一个 2-4 人可以玩的简单游戏。这是一款在一个 iphone/ipod touch 上玩的游戏,因此不需要联网。当游戏开始时,用户将选择要玩的玩家数量。

我需要为每个玩家创建 Player 类的实例。我的问题是我如何编码以便只制作所需数量的类并且它们都以不同的方式命名。我想到了以下方法,但我知道这行不通。

假设我有一个名为“playerNames”的数组,用于存储游戏中玩家的姓名。

for (int i = 0; i < [playerNames count]; i++) {

     Player *playeri = [[Player alloc] init];

     //other code

}

我不能只将“i”作为循环的计数器放在那里并得到四个实例,命名为 player1、player2 等。我该怎么做?

提前感谢您的帮助。

【问题讨论】:

    标签: iphone objective-c xcode


    【解决方案1】:

    您不能即时创建变量实例 - 您需要一个集合来存储生成的玩家。 C 数组或 NSMutableArray 可以很好地工作。您可以将此集合添加到您的控制器或视图中,让玩家可以通过游戏访问。

    此外,您可能希望使用 autorelease 自动释放玩家,或者在您的 dealloc 方法中释放集合中的项目以避免内存泄漏。

    这是一些使用 NSMutableArray 的代码,我假设您会添加到您的类接口中(并在某处初始化,通常在 viewDidLoad 中)

    -(void) CreatePlayers:(int)playerCount
    {
      for( int i = 0; i < [playerNames count]; i++ )
      {
          [playersArray insertObject:[[[Player alloc] init] autorelease] 
                             atIndex:i];
      }
    }
    

    【讨论】:

      【解决方案2】:

      您不能像这样以编程方式准确命名变量。

      但是,您可以创建这些对象并将它们添加到 NSMutableArray,然后再调用它们。

      如果您真的想将“PlayerN”名称与每个对象相关联,请使用 NSMutableDictionary。将播放器对象存储为键 @"PlayerN"(一个 NSString)的值。

      可以这样创建密钥:

      NSString *key = [NSString stringWithFormat:@"Player%d", i];
      

      【讨论】:

        【解决方案3】:

        对此最基本的解决方案是将玩家存储在数组或字典中(键入玩家名称)。采用数组方式:

        // assume we have an NSArray property, players
        NSMutableArray *tempPlayers = [NSMutableArray arrayWithCapacity:[playerNames count]];
        for (NSString *name in playerNames) {
          Player *player = [[Player alloc] init];
          [tempPlayers addObject:player];
          [player release];
        }
        self.players = tempPlayers;
        

        您现在可以通过调用objectAtIndex:players 属性访问每个玩家。

        关于设计的一句话——首先,您是否考虑过在您的 Player 类中添加一个 name 属性?在您捕获这些信息之后,这似乎是一个自然的存储位置。例如:

        for (NSString *name in playerNames) {
          // you might also have a designated initializer
          // e.g. [[Player alloc] initWithName:name]
        
          Player *player = [[Player alloc] init];
          player.name = name;
          [tempPlayers addObject:player];
          [player release];
        }
        

        总的来说,这是最简单的工作,也是我现在要做的所有事情。不过,未来……

        在某些时候,您可能会发现自己引入了某种 Game 类,代表您的用户创建的每个新游戏。这将是存储玩家数组的自然场所,并且可以让您构建更具凝聚力的界面,例如:

        Game *newGame = [[Game alloc] init];
        for(NSString *name) in playerNames) {
          [newGame addPlayerNamed:name];
        }
        

        您的 Game 类将封装玩家数组,addPlayerNamed 方法将封装创建新 Player 并将其存储在该数组中的过程,从而使您的控制器代码更加简单(并且意图揭示)在这个过程中。

        这样做的另一个好处是,它为您提供了一种能够在整个应用程序中访问这些数据的方法,而不是将其绑定在这个特定的控制器中。您可以实现对“currentGame”的某种类似单例的访问。当然不是真正的单身人士,但这样的事情会很好用:

        Game *newGame = [[Game alloc init];
        .. // configure game as above
        [Game setCurrentGame:newGame];
        

        所以现在,当您需要访问当前游戏(或玩家)信息时:

        // in some other controller
        Game *currentGame = [Game currentGame];
        for(Player *player in currentGame.players) {
          // etc...
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-20
          • 1970-01-01
          相关资源
          最近更新 更多