Как определить, находится ли объект в массиве на основе значения свойства / как использовать селекторы? - PullRequest
1 голос
/ 06 января 2012

Я все еще пытаюсь понять, как работают селекторы и динамическая типизация в задаче c. По сути, я пытаюсь реализовать этот метод (показано ниже в python / pseudocode, то же самое на самом деле: P)

def isInArray(value, array, test):
    for item in array:
        if test(item) == value:
            return True
    return False

test = lambda obj: obj.property

Мой код цели c:

+ (BOOL)value:(id)value:
    isInArray:(NSMutableArray *)array 
usingSelector:(SEL)selector {
    for (id item in array) {
        if (value == [item selector]) {
            return YES;
        }
    }
    return NO;
}

Однако, это выдает ошибку компиляции, жалуясь, что я сравниваю два типа указателей (id и SEL) в операторе if.

Разве не должен ли оператор if сравнивать значение объекта с объектом, возвращаемым при запуске селектора SEL для объекта arritem? Другими словами, почему он считает, что он сравнивает объект с SEL (я не вижу, что бы там возвращало SEL)

Ответы [ 2 ]

3 голосов
/ 06 января 2012

Оформить заказ performSelector в NSObject. Условное выражение будет выглядеть так:

if (value == [item performSelector:selector])

Используя Key Value Coding (KVC), ваш код может стать еще проще. Скажем, у вас есть массив с именем people, где каждый человек является объектом класса Person. Person имеет свойства firstName и lastName, и вы хотите получить всех людей, чье имя совпадает с "John" из массива people. Вы можете получить массив всех имен, а затем найти имя "John" в этом массиве.

NSArray *firstNames = [people valueForKey:@"firstName"];
if ([firstNames containsObject:@"John"]) {
  ..
}

Несмотря на то, что мы используем valueForKey, на самом деле он вызывает метод firstName и не имеет прямого доступа к значению.

0 голосов
/ 06 января 2012

хотя бы одну ошибку я вижу в определении метода. Нет необходимости добавлять двоеточие после имени переменной (в вашем случае value). И вы должны использовать performSelector: для проверки объекта с помощью селектора.

+ (BOOL)value:(id)value
    isInArray:(NSMutableArray *)array 
usingSelector:(SEL)selector {
    for (id item in array) {
        if ([item performSelector:selector] == value) {
            return YES;
        }
    }
    return NO;
}

В некоторых случаях вам нужно будет использовать isEqualTo: или isEqualToString: (если вы работаете со строками) вместо ==, поскольку == вернет true, если это тот же объект.

Кроме того, если вам нужно просто проверить наличие какого-либо объекта в NSArray, вы можете использовать containsObject: (вернуть true, если оно есть) и indexOfObjectPassingTest: (вернуть индекс объекта или 'NSNotFound')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...