NSMutableArray против NSArray, который лучше - PullRequest
10 голосов
/ 21 ноября 2011

Это немного глупый вопрос, но если я хочу добавить объект в массив, я могу сделать это как с NSMutableArray, так и с NSArray, что мне следует использовать?

NSMutableArray * array1;
[array1 addObject:obj];
NSArray * array2;
array2 = [array2 arrayByAddingObject:obj];

Ответы [ 6 ]

9 голосов
/ 21 ноября 2011

NSMutableArray не является потокобезопасным, а NSArray -.Это может быть огромной проблемой, если вы используете многопоточность.
NSMutableArray и NSArray оба построены на CFArray, производительность / сложность должны быть одинаковыми.Время доступа к значению в массиве гарантированно будет худшим O (lg N) для любой реализации, текущей и будущей, но часто будет O (1) (постоянное время).Операции линейного поиска аналогично имеют сложность O (N * lg N) в худшем случае, хотя обычно границы будут более жесткими и так далее.Операции вставки или удаления, как правило, будут линейными по количеству значений в массиве, но в некоторых реализациях могут быть явно равны O (N * lg N) в худшем случае.

8 голосов
/ 21 ноября 2011

При принятии решения, что лучше всего использовать:

NSMutableArray в основном используется, когда вы создаете коллекции и хотите изменить их. Думайте об этом как о динамическом.

NSArray используется только для чтения и либо:

  • используется для заполнения NSMutableArray, для выполнения модификаций
  • используется для временного хранения данных, которые не предназначены для редактирования

Что вы на самом деле делаете здесь:

NSArray * array2;
array2 = [array2 arrayByAddingObject:obj];

- вы создаете новый NSArray и меняете указатель на местоположение созданного вами нового массива.

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

если вы все еще хотите это сделать, вам нужно будет выполнить очистку следующим образом:

NSArray *oldArray;
NSArray *newArray;
newArray = [oldArray arrayByAddingObject:obj];
[oldArray release];

Но лучше всего делать следующее:

NSMutableArray *mutableArray;
// Initialisation etc
[mutableArray addObject:obj];
8 голосов
/ 21 ноября 2011

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

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

1 голос
/ 21 сентября 2018

Объект NSArray управляет неизменным массивом, то есть после создания массива вы не можете добавлять, удалять или заменять объекты. Однако вы можете изменить отдельные элементы сами (если они поддерживают изменение). Изменчивость коллекции не влияет на изменчивость объектов внутри коллекции. Вы должны использовать неизменяемый массив, если массив редко изменяется или изменяется оптом.

Объект NSMutableArray управляет изменяемым массивом, который позволяет добавлять и удалять записи, выделяя память по мере необходимости. Например, учитывая объект NSMutableArray, который содержит только один объект собаки, вы можете добавить другую собаку, или кошку, или любой другой объект. Вы также можете, как и в случае с объектом NSArray, изменить имя собаки - и в целом все, что вы можете сделать с объектом NSArray, вы можете сделать с объектом NSMutableArray. Вы должны использовать изменяемый массив, если массив изменяется постепенно или очень велик - поскольку для больших коллекций требуется больше времени для инициализации.

1 голос
/ 20 апреля 2017

Даже вопрос и ответ очень старые, кто-то должен это исправить.

  1. Что значит «лучше»? Лучше что? Ваша Q утечки информации, в чем проблема, и это в значительной степени основано на мнении. Тем не менее, он не закрыт.

Если вы говорите о производительности, вы можете измерить ее самостоятельно. Но помните, Дональд Кнут: «Преждевременная оптимизация - корень всего зла».

  1. Если я серьезно отнесусь к вашему Q, «лучше» может означать производительность во время выполнения, объем памяти или архитектуру. По первым двум темам легко проверить себя. Так что никакого ответа не требуется.

С архитектурной точки зрения все усложняется.

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

Можно сказать, что это не очень хорошая идея, особенно если подумать о Барбаре и Джанетт и что существует проблема круг-эллипс , которую нелегко решить , Тем не менее, это как есть.

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

Однако изменчивость - это еще один корень зла. Поэтому: если это возможно, всегда создавайте экземпляр NSArray в качестве конечного результата. Запишите это в своих документах, если вы возвращаете этот экземпляр из метода (особенно getter) или нет, чтобы каждый мог положиться на неизменность или нет. Это предотвращает неожиданные изменения "за сценой". Это важно, а не 0,000000000003 сек времени выполнения или 130 байт памяти.

0 голосов
/ 07 июля 2016

Этот тест дает лучший ответ:

Метод 1:

NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
NSMutableArray *mutableItems = [[NSMutableArray alloc] initWithCapacity:1000];
for (int i = 0; i < 10000; i++) {
    [mutableItems addObject:[NSDate date]];
}
NSTimeInterval  end = [NSDate timeIntervalSinceReferenceDate];
NSLog(@"elapsed time = %g", (end - start) * 1000.0);

Метод 2:

...
NSArray *items = [[[NSArray alloc] init] autorelease];
or (int i = 0; i < 10000; i++) {
    items = [items arrayByAddingObject:[NSDate date]];
}
...

Выход:

Method 1: elapsed time = 0.011135 seconds.    
Method 2: elapsed time = 9.712520 seconds.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...