Я хочу, чтобы все объекты в массиве выполняли селектор. Я обнаружил соответствующий метод makeObjectsPerformSelector:
, но у меня есть вопрос. Если я использую его в массиве, изменит ли он существующий массив или вернет новый? Если он изменяет существующий объект, каким будет самый простой способ вернуть новый массив с примененным селектором?
MakeObjectsPerformSelector:
Ответ 1
makeObjectsPerformSelector: будет запускать этот селектор против каждого объекта в массиве. Если эти объекты будут изменены селектором, они будут изменены. Он ничего не возвращает. Теперь есть catch, который по умолчанию большинство копий в Cocoa являются неглубокими копиями, что означает, что вы получаете новый массив, но базовые объекты, на которые он указывает, являются одинаковыми объектами. Вам нужно будет использовать initWithArray: copyItems, чтобы он также скопировал элементы корневого уровня. Если вы хотите, чтобы новый массив, содержащий измененные объекты, а также старый массив, сделал что-то вроде этого:
NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];
Ответ 2
Если я использую его в массиве, изменит ли он существующий массив или вернет новый?
Нет.
Прежде всего, прочитайте подпись:
- (void)makeObjectsPerformSelector:(SEL)aSelector
void
, без звезд после него, означает "ничего не возвращает".
Во-вторых, обратите внимание, что это метод NSArray, который является неизменным классом. Поэтому makeObjectsPerformSelector:
не мутирует принимающий массив, потому что это невозможно.
Существует NSMutableArray, и поскольку это подкласс NSArray, он наследует makeObjectsPerformSelector:
. Однако, если NSMutableArray изменил поведение этого метода, в его документации будет свой собственный список для метода (см. Множество определений init
в документации различных классов). Там нет такого листинга, поэтому вы можете спокойно (и правильно) сделать вывод, что -[NSMutableArray makeObjectsPerformSelector:]
работает точно так же, как -[NSArray makeObjectsPerformSelector:]
.
Объекты могут изменять себя в ответ на ваше сообщение, но сам массив будет содержать те же объекты после makeObjectsPerformSelector:
, что и раньше.
Ответ 3
В дополнение к другим ответам, если вы хотите создать новый массив с результатом вызова метода, вы можете сделать это:
NSArray *derivedArray = [originalArray valueForKey:@"foo"];
Это будет только, если ваши объекты могут обрабатывать сообщение '-valueForKey: @ "foo" ' и, очевидно, подходят только для методов, которые не принимают аргументов и возвращают значение, отличное от нуля.
Ответ 4
Надеюсь, я правильно это интерпретирую...
Если вы выполняете [myArray makeObjectsPerformSelector: someSelector], вы фактически просто выполняете итерацию через myArray и отправляете сообщение селектора каждому объекту. Массив не изменяется, поскольку makeObjectsPerformSelector не может изменять его содержимое.
Итак, в конце концов, у вас есть тот же массив с теми же объектами.