如何从NSMutableArray设置实例变量?

时间:2012-03-06 10:39:28

标签: ios for-loop nsmutablearray instance-variables

所以我正处于开始减少意大利面条代码的地步。

所以现在,我有11个不同的恐龙图像,我使用“for”循环放入NSMutableArray。我还声明了CCSprite实例变量,其中我希望我可以设置每个恐龙图像,以便我可以检查边界框,设置位置等。所以我将数组中的每个对象指向一个实例变量到目前为止,我有这段代码:

.h文件:

CCSprite *dinosaur1_c;
CCSprite *dinosaur2_c;
CCSprite *dinosaur3_c;
CCSprite *dinosaur4_c;
CCSprite *dinosaur5_c;
CCSprite *dinosaur6_c;
CCSprite *dinosaur7_c;
CCSprite *dinosaur8_c;
CCSprite *dinosaur9_c;
CCSprite *dinosaur10_c;
CCSprite *dinosaur11_c;

.m文件

NSMutableArray *dinoSprites = [[NSMutableArray alloc] init];

for( int i = 1, j = 0; i <= 11 && j <= 10; i++, j++ )
{
    id dino = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"dinosaur%d-c.png", i]];
    [dinoSprites addObject:dino];
    [sceneSpriteBatchNode addChild:dino];
}


dinosaur1_c = (CCSprite *)[dinoSprites objectAtIndex:0];
dinosaur2_c = (CCSprite *)[dinoSprites objectAtIndex:1];
dinosaur3_c = (CCSprite *)[dinoSprites objectAtIndex:2];
dinosaur4_c = (CCSprite *)[dinoSprites objectAtIndex:3];
dinosaur5_c = (CCSprite *)[dinoSprites objectAtIndex:4];
dinosaur6_c = (CCSprite *)[dinoSprites objectAtIndex:5];
dinosaur7_c = (CCSprite *)[dinoSprites objectAtIndex:6];
dinosaur8_c = (CCSprite *)[dinoSprites objectAtIndex:7];
dinosaur9_c = (CCSprite *)[dinoSprites objectAtIndex:8];
dinosaur10_c = (CCSprite *)[dinoSprites objectAtIndex:9];
dinosaur11_c = (CCSprite *)[dinoSprites objectAtIndex:10];

这段代码确实有效,但我确信它可以减少。如何使用“for”循环设置每个实例变量?

我在其他方法中使用这些实例变量来设置位置,检查碰撞/交叉,淡入等等。

我使用等效代码来更好地解释我正在尝试做的事情:

NSMutableArray *dinoSprites = [[NSMutableArray alloc] init];

for( int i = 1, j = 0; i <= 11 && j <= 10; i++, j++ )
{
    id dino = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"dinosaur%d-c.png", i]];
    [dinoSprites addObject:dino];
    [sceneSpriteBatchNode addChild:dino];

    // Set instance variables
    dinosaur%i_c = (CCSprite *)[dinoSprites objectAtIndex:j];
}

有没有办法实现我的要求?经过2.5小时的搜索,我仍然没有想出任何东西。只是找到动画帧的解决方案。

我是否遗漏了一些小东西,或者我是否应该采用不同的方式指向阵列中的每个图像来设置位置,淡入淡出,检查边界框等?

非常感谢任何想法/投入!感谢您抽时间阅读! :d

2 个答案:

答案 0 :(得分:3)

您应该只拥有一个CCSprite,而不是拥有11个NSArray个实例变量。

所以在你的.h:

@property (strong) NSArray *dinoSprites;

在你的.m中,做一个

@synthesize dinoSprites;

然后用以下代码替换问题中的代码:

NSMutableArray *newDinoSprites = [[NSMutableArray alloc] init];

for( int i = 1, j = 0; i <= 11 && j <= 10; i++, j++ )
{
    id dino = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"dinosaur%d-c.png", i]];
    [newDinoSprites addObject:dino];
    [sceneSpriteBatchNode addChild:dino];
}

self.dinoSprites = [newDinoSprites copy];

然后,只要您需要参考以前的内容,比如dinosaur8_c,您只需使用(CCSprite *)[dinoSprites objectAtIndex:7]

答案 1 :(得分:2)

  

有没有办法实现我的要求? 2.5小时后   搜索,我仍然没有想出什么。找到解决方案   用于动画帧。

您似乎想要一个值为另一个变量的变量,以便您可以迭代一组ivars。我可以想出两种方法来做你喜欢的事情。

第一种方法是使用每个变量的地址,即指向每个变量的指针。由于指针本身是标量值,而不是对象,因此您需要使用C风格的数组:

CCSprite *ivars[] = {&dinosaur1_c, &dinosaur2_c, &dinosaur3_c, &dinosaur4_c};
for (int i = 0; i < 4; i++) {
    *(ivars[i]) = [dinoSprites objectAtIndex:i];
}

第二种方法是使用键值编码。将每个ivar的名称构造为字符串,然后将其用作-setValue:forKey:调用中的键,如下所示:

NSString *name;
for (int i = 0; i < [dinoSprites count]; i++) {
    name = [NSString stringWithFormat:@"dinosaur%d_c", i];
    [self setValue:[dinoSprites objectAtIndex:i] forKey:name];
}

所有这一切,我强烈建议您不要采取前两种方法中的任何一种来解决您的问题。对于你的问题,很可能有更好的解决方案,不涉及为每只恐龙分别设置一个ivar。你已经将恐龙放在一个阵列中,因此不需要为每个恐龙创建一个单独的ivar。作为一般规则,如果您发现自己创建了这样的编号变量,您可能应该退后一步并重新思考您正在做的事情 - 对变量进行编号是一个强烈的信号,您应该使用数组。

因此,在您的情况下,我认为您没有任何理由不能使用代码中已有的阵列。您可以使用dinosaur6_c代替[dinoSprites objectAtIndex:6],而不是for (int i = 0; i < [dinoSprites count]; i++) { int row = i / DINOS_PER_ROW; int column = i % DINOS_PER_ROW; CGPoint position = CGPointMake(row * rowHeight, column * columnWidth); [[dinoSprites objectAtIndex:i] setPosition:position]; } 。但是如果你想办法用相同的代码处理所有的恐龙,你就会真正清理你的代码,这样你就不会在你的阵列中硬编码特定的标记。例如,如果你需要将每只恐龙设置到不同的位置,至少有两种很好的方法可以解决它。一种是根据索引计算位置(如果可能)。如果你以常规方式布置恐龙,就像在3 x n网格上一样,你可以做到这一点:

NSArray *positions = [NSArray arrayWithContentsOfURL:someURL]; // read positions from a property list
NSAssert([positions count] >= [dinoSprites count], @"Not enough positions!");
for (int i = 0; i < [dinoSprites count]; i++) {
    CGPoint position = [[positions objectAtIndex:i] pointValue];
    [[dinoSprites objectAtIndex:i] setPosition: position;
}

如果每个恐龙的位置不能从数组中的索引计算出来,那么你现在可能正在对代码中的位置进行硬编码。您可以通过至少将位置移动到数组来清理它,也许可以通过从数据文件中读取该数组来清除它。这将使您的代码更短,更易于理解,更易于维护:

positions

当然,我只是在这里使用精灵的位置作为例子。您可以对要应用于恐龙的任何属性执行完全相同的操作,您甚至可以一次完成所有这些操作。您可以加载一个字典数组,而不是从属性列表加载的{{1}}数组,其中每个字典包含许多属性(颜色,喜欢的食物,速度,饥饿程度等)。