Подтвердить что ты не робот

MakeObjectsPerformSelector:

Я хочу, чтобы все объекты в массиве выполняли селектор. Я обнаружил соответствующий метод makeObjectsPerformSelector:, но у меня есть вопрос. Если я использую его в массиве, изменит ли он существующий массив или вернет новый? Если он изменяет существующий объект, каким будет самый простой способ вернуть новый массив с примененным селектором?

4b9b3361

Ответ 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 не может изменять его содержимое.

Итак, в конце концов, у вас есть тот же массив с теми же объектами.