makeObjectsPerformSelector: - PullRequest
       9

makeObjectsPerformSelector:

17 голосов
/ 19 февраля 2009

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

Ответы [ 5 ]

29 голосов
/ 19 февраля 2009

makeObjectsPerformSelector: собирается запустить этот селектор для каждого объекта в массиве. Если эти объекты изменены селектором, они будут изменены. Ничего не возвращает. Теперь есть одна загвоздка, которая заключается в том, что по умолчанию большинство копий в Какао являются неглубокими копиями, что означает, что вы получаете новый массив, но базовые объекты, на которые он указывает, являются теми же объектами. Вам нужно будет использовать initWithArray: copyItems, чтобы он также копировал элементы корневого уровня. Если вы хотите новый массив, содержащий измененные объекты, а также старый массив, сделайте что-то вроде этого:

NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];
15 голосов
/ 19 февраля 2009

Если я использую его в массиве, он изменит существующий массив или вернет новый?

номер

Прежде всего, прочитайте подпись:

- (void)makeObjectsPerformSelector:(SEL)aSelector

void без звездочек после него означает «ничего не возвращает».

Во-вторых, обратите внимание, что это метод NSArray, который является неизменным классом. Следовательно, makeObjectsPerformSelector: не изменяет принимающий массив, потому что это невозможно.

Существует NSMutableArray, и, поскольку это подкласс NSArray, он наследует makeObjectsPerformSelector:. Однако, если NSMutableArray изменил поведение этого метода, его документация будет иметь свой собственный листинг для метода (см. Множество определений init в документации различных классов). Нет такого списка, поэтому вы можете безопасно (и правильно) сделать вывод, что -[NSMutableArray makeObjectsPerformSelector:] работает точно так же, как -[NSArray makeObjectsPerformSelector:].

Объекты могут изменить себя в ответ на ваше сообщение, но сам массив будет содержать те же объекты после makeObjectsPerformSelector:, что и до него.

7 голосов
/ 19 февраля 2009

В дополнение к другим ответам, если вы делаете хотите создать новый массив с результатом вызова метода, вы можете сделать это:

NSArray *derivedArray = [originalArray valueForKey:@"foo"];

Это будет только , если ваши объекты могут обрабатывать сообщение '-valueForKey: @ "foo"' и, очевидно, подходят только для методов, которые не принимают аргументов и возвращают ненулевое значение. 1008 *

2 голосов
/ 19 февраля 2009

Надеюсь, я правильно понимаю ...

Если вы делаете [myArray makeObjectsPerformSelector: someSelector], вы фактически просто перебираете myArray и отправляете сообщение селектора каждому объекту. Массив не изменяется, поскольку makeObjectsPerformSelector не разрешено изменять его содержимое.

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

0 голосов
/ 19 октября 2018

В следующем примере вы можете увидеть, как создается один superView и к нему добавляется 10 подпредставлений, затем каждому из них отправляется removeFromSuperView (метод, который существует в классе view), и результатом является нулевое подпредставление. в superView.

Если вы знакомы с JavaScript и пытаетесь найти что-то вроде map в JavaScript, это не так. map запустить функцию над каждым элементом массива и заменить его результатом, но здесь makeObjectsPerformSelector запустить метод, который существует в каждом объекте массива.

UIView* superView = [[UIView alloc] initWithFrame:CGRectZero];

for(int i = 0; i < 10; i++){
    UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
    [superView addSubview:view];
}

NSLog(@"count = %lu", (unsigned long)[superView.subviews count]); // 10
[superView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; // removeFromSuperview is exist in `view`, you can call [view removeFromSuperview];
NSLog(@"count = %lu", (unsigned long)[superView.subviews count]); // 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...