NSArray в NSArray не возвращает изображение, которое я хочу - PullRequest
1 голос
/ 12 мая 2010

У меня есть фрагмент кода, который я не могу заставить работать.

NSUInteger i;
//NSMutableArray *textures = [[NSMutableArray alloc] initWithCapacity:kNumTextures];
//NSMutableArray *texturesHighlighted = [[NSMutableArray alloc] initWithCapacity:kNumTextures];

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


for (i = 1; i <= kNumTextures; i++)
{
    NSString *imageName = [NSString stringWithFormat:@"texture%d.png", i];
    NSString *imageNameHighlighted = [NSString stringWithFormat:@"texture%d_select.png", i];
    UIImage *image = [UIImage imageNamed:imageName];
    UIImage *imageHighlighted = [UIImage imageNamed:imageNameHighlighted];
    //NSArray *pics = [[NSArray alloc] initWithObjects:(UIImage)image,(UIImage)imageHighlighted,nil];
    NSArray *pics = [NSArray arrayWithObjects:image,imageHighlighted,nil];
    [textures addObject:pics];
    [pics release];
}

//select randomly the position of the picture that will be represented twice on the board
NSInteger randomTexture = arc4random()%([textures count]+1);

//extract image corresponding to the randomly selected index
//remove corresponding pictures from textures array
NSArray *coupleTexture = [textures objectAtIndex:randomTexture];
[textures removeObjectAtIndex:randomTexture];

//create the image array containing 1 couple + all other pictures
NSMutableArray *texturesBoard = [[NSMutableArray alloc] initWithCapacity:kNumPotatoes];

[texturesBoard addObject:coupleTexture];
[texturesBoard addObject:coupleTexture];
[coupleTexture release];

NSArray *pics = [[NSArray alloc] init];
for (pics in textures)  {
    [texturesBoard addObject:pics];
}
[pics release];

//shuffle the textures
//[texturesBoard shuffledMutableArray];

//Array with masks
NSMutableArray *masks= [[NSMutableArray alloc] init];

for (i = 1; i <= kNumMasks; i++)
{
    NSString *maskName = [NSString stringWithFormat:@"mask%d.png", i];
    UIImage *mask = [UIImage imageNamed:maskName];
    //NSArray *pics = [[NSArray alloc] initWithObjects:mask,nil];
    [masks addObject:mask];

    //[pics release];
    [maskName release];
    [mask release];
}

//Now mask all images in texturesBoard
NSMutableArray *list = [[NSMutableArray alloc] init];
for (i = 0; i <= kNumMasks-1; i++)
{
    //take on image couple from textures
    NSArray *imgArray = [texturesBoard objectAtIndex:i];
    UIImage *mask = [masks objectAtIndex:i];

    //mask it with the mask un the array at corresponding index
    UIImage *img1 =(UIImage *) [imgArray objectAtIndex:0];
    UIImage *img2 =(UIImage *) [imgArray objectAtIndex:1];
    UIImage *picsMasked = [self maskImage:(UIImage *)img1 withMask:(UIImage *)mask];
    UIImage *picsHighlightedMasked = [self maskImage:(UIImage *)img2 withMask:(UIImage *)mask];
    //Init image with highlighted status
    TapDetectingImageView *imageView = [[TapDetectingImageView alloc] initWithImage:picsMasked imageHighlighted:picsHighlightedMasked];
    [list addObject:imageView];
}

Проблема здесь в том, что: img1 и img2 - это не изображения, а NSArray с несколькими записями. Я не могу понять, почему ... любой свежий дух мог бы дать мне ключ к разгадке.

Спасибо большое.

Ответы [ 2 ]

3 голосов
/ 12 мая 2010

Давайте начнем с проблемы с памятью в первом цикле for. Есть перевыпуск:

NSArray *pics = [NSArray arrayWithObjects:image,imageHighlighted,nil];
[textures addObject:pics];
[pics release];   // <-- pics is overreleased since it is created autoreleased

Вторая проблема с памятью. coupleTexture переиздан.

NSArray *coupleTexture = [textures objectAtIndex:randomTexture];
[textures removeObjectAtIndex:randomTexture];

//create the image array containing 1 couple + all other pictures
NSMutableArray *texturesBoard = [[NSMutableArray alloc] initWithCapacity:kNumPotatoes];

[texturesBoard addObject:coupleTexture];
[texturesBoard addObject:coupleTexture];
[coupleTexture release];      // <--- coupleTexture is autoreleased since it is returned by objectAtIndex: and not retained

Вы должны научиться делать быстрые перечисления. Это должно выглядеть так:

for (NSArray *pics in textures)  {
    [texturesBoard addObject:pics];
}

Больше проблем с памятью в масках цикла:

NSString *maskName = [NSString stringWithFormat:@"mask%d.png", i];
UIImage *mask = [UIImage imageNamed:maskName];
//NSArray *pics = [[NSArray alloc] initWithObjects:mask,nil];
[masks addObject:mask];

//[pics release];
[maskName release];     // <-- overreleased.. was created by stringWithFormat
[mask release];         // <-- overreleased.. same same

Следовательно, массив масок не освобождается ... а также массив списков, созданный сразу после цикла ...

О, мальчик. Здесь я должен остановиться, так как у меня тоже начинаются головные боли;) Вещи, которые вы должны выучить:

  • Только release что вы создали с помощью init или что вы retained явно
  • Правильно используйте быстрое перечисление
  • Структурируйте ваш код ... Возможно, извлеките некоторые циклы for для разделения методов и отладьте их результаты отдельно.

Не расстраивайся. Продолжайте учиться:)

0 голосов
/ 12 мая 2010

Этот код вызвал у меня головную боль. Вам действительно нужно это исправить и инкапсулировать в некоторые методы или функции, особенно если вы настаиваете на переназначении одних и тех же имен переменных снова и снова.

Я думаю, что ваша проблема здесь:

NSArray *pics = [[NSArray alloc] init];
for (pics in textures)  {
    [texturesBoard addObject:pics];
}
[pics release];

Сначала вы присваиваете инициализированный пустой массив, затем вы присваиваете ему массивы в текстурах, затем вы освобождаете последний присвоенный вам массив. Думаю, что это шифрование массива texturesBoard. Скорее всего, это убивает один из массивов, из-за чего размер массива получается неправильным.

Это должно быть просто:

NSArray *pics;
for (pics in textures)  {
    [texturesBoard addObject:pics];
}
...