Терминологический вопрос, касающийся зацикливания через NSArray в Objective-C - PullRequest
0 голосов
/ 16 сентября 2009

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

пример кода:

NSMutableArray *bin = [NSMutableArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil];
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"a1", @"b2", @"c3", @"e4", nil];

NSMutableArray *listHolder = list; // can't mutate 'list' within loop so create a holder

for (int i = 0; i < [list count]; i++) {
    [listHolder replaceObjectAtIndex:i withObject:[bin objectAtIndex:i]];
}

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

Ответы [ 4 ]

4 голосов
/ 16 сентября 2009

Это совершенно верно:

NSMutableArray *bin = [NSMutableArray arrayWithObjects:@"0", @"1", …, @"7", nil];
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"a1", …, @"e4", nil];

// NSInteger should be used instead of int
for (NSInteger i = 0; i < [list count]; i++) {
    [list replaceObjectAtIndex:i withObject:[bin objectAtIndex:i]];
}

Вы не можете изменять массив внутри цикла for … in или NSEnumerate, но использование индекса вполне допустимо.

Что меня беспокоит, так это ваше неправильное понимание указателей.
Если бы это был цикл, в котором вам не разрешалось изменять массив, это не скопировало бы массив, а только указатель на массив, эффективно изменив массив, на который вы не имеете права. (Я даже не уверен, работает ли это.)

Вместо простого копирования указателя

// can't mutate 'list' within loop so create a holder
NSMutableArray *listHolder = list;

сделать истинную копию:

NSMutableArray *copy = [[list mutableCopy] autorelease];

Если мне действительно нужно сделать копию, я пытаюсь назвать ее в соответствии с ее содержанием. Например:

NSMutableArray *views;
NSMutableArray *reorderedViews = [views mutableCopy];

// reorder reorderedViews

Иногда трудно найти достаточно хорошее имя, тогда я обычно просто использую nameCopy.

1 голос
/ 16 сентября 2009

В этом контексте listHolder будет называться копией .

В вашем коде есть ошибка. Эта строка фактически не делает копию, она только позволяет listHolder и list ссылаться на один и тот же объект массива:

NSMutableArray *listHolder = list;

Это будет фактическая копия:

NSMutableArray *listHolder = [list mutableCopy];

Убедитесь, что вы используете mutableCopy, а не просто copy, если хотите, чтобы копия была изменяемой. Метод copy будет возвращать неизменяемые варианты для всех изменяемых классов, таких как NSMutableSet, NSMutableDictionary и т. Д.

Также, как уже отмечали другие, только в цикле for (item in collection) нумерованная коллекция не может быть видоизменена. В обычной for (;;) мутация совершенно нормальная, но может привести к странному результату, если количество предметов в коллекции изменится.

1 голос
/ 16 сентября 2009

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

Сказав, что, как правило, если у вас нет конкретных имен в подобной ситуации, тогда люди называют исходный список «источником» (src), а окончательный список - «местом назначения» (dst), как в Операция в стиле стряхивания памяти.

0 голосов
/ 17 сентября 2009

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

...