Повторное использование NSMutableArray - PullRequest
1 голос
/ 25 января 2010

При попытке повторно использовать существующий NSMutableArray (для экономии памяти) я получаю некоторые утечки (наблюдаемые инструментами).

По сути, я создаю NSMutableArray, заполняю его объектами (UIImages) и передаю его другому объекту, который его сохраняет. Однако теперь мне нужно снова использовать NSMutableArray. Я подумал, что я бы выпустил все его объекты, очистил его, и все было бы хорошо, но Instruments сообщает об утечке объекта CALayer (??) из того самого метода, который выглядит примерно так:

NSString *fileName;
NSMutableArray *arrayOfImages = [[NSMutableArray alloc] init];

// fill the array with images
for(int i = 0; i <= 7; i++) {
    fileName = [NSString stringWithFormat:@"myImage_%d.png", i];
    [arrayOfImages addObject:[UIImage imageNamed:fileName]];
}

// create a button with the array
aButton = [[CustomButtonClass buttonWithType:UIButtonTypeCustom] 
                   initWithFrame:someFrame
                   imageArray:arrayOfImages];

// release its objects
for(int i = 0; i < [arrayOfImages count]; i++) {
    [[arrayOfImages objectAtIndex:i] release];
}
// empty array
[arrayOfImages removeAllObjects];

// fill it with other images
for(int i = 0; i <= 7; i++) {
    fileName = [NSString stringWithFormat:@"myOtherImage_%d.png", i];
    [arrayOfImages addObject:[UIImage imageNamed:fileName]];
}
// create another button with other images (same array)
aSecondButton = [[CustomButtonClass buttonWithType:UIButtonTypeCustom] 
                   initWithFrame:someFrame
                   imageArray:arrayOfImages];

[arrayOfImages release];

Для ясности мой метод инициализации кнопки выглядит следующим образом:

- (id)initWithFrame:(CGRect)frame 
      images:(NSArray *)imageArray
{
    if(self = [super initWithFrame:frame]) {
        myImageArray = [[NSArray arrayWithArray:imageArray] retain];
    }
return self;
}

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

Ответы [ 3 ]

6 голосов
/ 25 января 2010

При попытке повторно использовать существующий NSMutableArray (для экономии памяти) я получаю некоторые утечки (наблюдаемые Instruments).

Массив занимает действительно небольшой объем памяти;Сохранено 4 байта на указатель (в 32-битной системе) + незначительные накладные расходы.Повторное использование массива для сохранения памяти - пустая трата времени во всех случаях, кроме самых необычных.

// release its objects
for(int i = 0; i < [arrayOfImages count]; i++) {
    [[arrayOfImages objectAtIndex:i] release];
}
// empty array
[arrayOfImages removeAllObjects];

Вы не сохранили объекты и, следовательно, не должны их освобождать!То, что ваше приложение не аварийно завершило работу после вышеперечисленного, указывает на то, что вы, вероятно, чрезмерно сохраняете объекты в другом месте.

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

В этом коде нет ничего, что возникало бы как утечка памяти.Как раз наоборот;вы перевыпускаете объекты.

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

4 голосов
/ 25 января 2010

Вам не нужна эта часть:

// release its objects
for(int i = 0; i < [arrayOfImages count]; i++) {
    [[arrayOfImages objectAtIndex:i] release];
}

Это против правила владения. Вы не сохранили изображения на

[arrayOfImages addObject:[UIImage imageNamed:fileName]];

так что вы не обязаны их выпускать. NSMutableArray сохраняет их при вызове -addObject, и поэтому NSMutableArray обязан освободить их, когда вызывается -removeObject или другие лица того же рода. Обнаруженная вами утечка может быть связана с тем, что система запуталась из-за чрезмерного выпуска ...

Я бы также порекомендовал выполнить «Построить и проанализировать» в XCode.

0 голосов
/ 25 января 2010

Инструмент "Утечки" сообщает вам, где объект, из которого произошла утечка, был первым , выделенным .Тот факт, что одно из изображений было пропущено, означает, что вы использовали это изображение где-то еще и не выпустили его там. Утечки не могут сказать вам, где, поскольку он не может показать вам код, который не существует.отметил, что это несколько удивительно, так как код «как есть» перегружает объекты и должен был аварийно завершить работу.Но тот факт, что он не потерпел крах, является хорошим признаком того, что вы используете изображения из массива и чрезмерно сохраняете их.

...