Вопрос

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

Это было полезно?

Решение

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

NSArray *newArray = [[NSArray alloc] initWithArray:oldArray copyItems:YES];
[newArray makeObjectsPerformSelector:@selector(doSomethingToObject)];

Другие советы

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

Нет.

Для начала прочитайте подпись:

- (void)makeObjectsPerformSelector:(SEL)aSelector

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

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

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

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

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

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

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

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

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

В итоге у вас есть тот же массив с теми же объектами.

В следующем примере вы можете увидеть один superView создается и к нему добавляется 10 подпредставлений, затем в каждое из них отправляется removeFromSuperView (метод, существующий в view class) и результатом является нулевой подпредставление в 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top