NSMutableArray -init vs. + arrayWithCapacity: - PullRequest
       2

NSMutableArray -init vs. + arrayWithCapacity:

10 голосов
/ 13 ноября 2009

У меня есть две функции, какую я должен использовать? Пожалуйста, объясните разницу.

A:

- (NSMutableArray *)FunctionA:(int)count {

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

 for (int i = 0; i < count; i++) {
  [a addObject:[NSNumber numberWithInt:0] ];
    }

    return [a autorelease];
}

B:

-(NSMutableArray *)FunctionB:(int)count {

 NSMutableArray *b = [NSMutableArray arrayWithCapacity:count];

 for (int i=0;i<count; i++){  
  [b addObject:[NSNumber numberWithInt:0] ];  
 }

 return b;  //  or [b autorelease] ?
}

Ответы [ 4 ]

28 голосов
/ 13 ноября 2009

Первый создает изменяемый массив без указания емкости. Это заставляет массив увеличиваться при добавлении элементов. Внутренне это, вероятно, сильно оптимизировано, чтобы происходить «порциями», но все равно необходимо увеличивать массив и выделять больше места при добавлении элементов.

Второй дает массиву подсказку (вам, вероятно, понадобится «так много» места), чтобы избежать накладных расходов на увеличение массива при добавлении известного количества объектов. Конечно, он все равно будет увеличиваться при необходимости (как если бы вы не указали емкость). Вы должны использовать этот подход, если вы уже знаете счет заранее. Это быстрее с большим количеством.

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

Кроме того, вы не выполняете автоматический выпуск B (как вы прокомментировали), потому что вы не создали изменяемый массив с помощью init - вы использовали удобный метод, который сделал это сам, что означает, что вы не несете ответственности за его освобождение. Как я уже упоминал в комментарии к другому ответу на ваш вопрос, вы также можете создать массив с помощью:

[[NSMutableArray alloc] initWithCapacity:capacity];

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

Помните, однако: сначала измерьте, а затем оптимизируйте при необходимости.

1 голос
/ 13 ноября 2009

В первом примере вы должны управлять памятью массива, поскольку вы создаете его, используя +alloc и -init (поэтому вам нужно отправить -autorelease на него).

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

Если вы хотите вернуть автоматически освобожденный массив, то второй вариант, вероятно, будет более предпочтительным, так как +arrayWithCapacity: возвратит уже автоматически выпущенный массив. Кроме того, поскольку возвращенный вам массив уже автоматически выпущен, вам не нужно отправлять -autorelease на него самостоятельно.

Если у вас возникли какие-либо проблемы с управлением памятью, тогда обязательно прочитайте Apple Руководство по управлению памятью .

1 голос
/ 13 ноября 2009

Изменяемые объекты по-прежнему должны выделять пространство, чтобы выделять количество по умолчанию, скажем, для 10 объектов. Если вы добавите 11-е число, изменяемый массив должен будет выделить новую память, скопировать элементы в новую память и освободить старую память.

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

0 голосов
/ 13 ноября 2009

Я бы использовал B:

плюсы, которые я вижу с этим

  • Размер массива не нужно будет изменять по мере увеличения
  • arrayWithCapacity: авто-релизы для вас, поэтому вам не нужно, это улучшает читаемость кода imho

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...