2010-05-31 2 views
16

У меня есть простой вопрос относительно кодирования xcode, но не знаю, почему вещи не работают, как я думаю. У меня есть массив объектов (пользовательские объекты). Я просто хочу проверить, находится ли он в массиве. Я использовал следующий код:NSArray containsObject метод

NSArray *collection = [[NSArray alloc] initWithObjects:A, B, C, nil]; //A, B, C are custom "Item" objects 
Item *tempItem = [[Item alloc] initWithLength:1 width:2 height:3]; //3 instance variables in "Item" objects 
if([collection containsObject:tempItem]) { 
    NSLog(@"collection contains this item"); 
} 

Я полагаю, что вышеуказанная проверка даст мне положительный результат, но это не так. Кроме того, я проверил, являются ли созданные объекты одинаковыми.

NSLog(@"L:%i W:%i H:%i", itemToCheck.length, itemToCheck.width, itemToCheck.height); 
for (int i = 0, i < [collection count], i++) { 
    Item *itemInArray = [collection objectAtIndex:i]; 
    NSLog(@"collection contains L:%i W:%i H:%i", itemInArray.length, itemInArray.width, itemInArrayheight); 
} 

В консоли, это то, что я получил:

L:1 W:2 H:3 
collection contains L:0 W:0 H:0 
collection contains L:1 W:2 H:3 
collection contains L:6 W:8 H:2 

Очевидно, что tempItem находится внутри collection массива, но ничего не отображается, когда я использую containsObject:, чтобы проверить его. Может ли кто-нибудь дать мне какое-то направление, в какой части я ошибаюсь? Большое спасибо!

ответ

40

В документации по [NSArray containsObject:] говорит:

Этот метод определяет, является ли anObject присутствует в приемнике посредством отправки IsEqual в: сообщение для каждого из объектов приемника (и передавая anObject в качестве параметра каждый isEqual: сообщение).

Проблема в том, что вы сравниваете ссылки на объекты, а не на значения объектов. Чтобы этот конкретный пример работал, вам нужно либо отправить [collection containsObject:] экземпляр переменной, которую он содержит (например, A, B, или C), либо вам необходимо переопределить метод [NSObject isEqual:] в вашем классе Item.

Это то, что ваш метод isEqual может выглядеть следующим образом:

- (BOOL)isEqual:(id)other { 
    if (other == self) 
     return YES; 
    if (!other || ![other isKindOfClass:[self class]]) 
     return NO; 
    if (self.length != other.length || self.width != other.width || self.height != other.height) 
     return NO; 
    return YES; 
} 

Для более эффективной реализации, вы можете посмотреть на этот question.

+1

О, извините, только опечатка для «Fruit», это должен быть «Item». Вы имеете в виду сравнение пользовательских объектов класса с помощью containsObject: не работает? – Anthony

+2

Он действительно работает, он просто сравнивается по умолчанию с использованием ссылки на ваш пользовательский объект. Если вы хотите сделать 'tempItem' равным' A' в приведенном выше примере, вам нужно просто создать этот метод 'isEqual' в вашем классе. – Senseful

+1

@ Энтони, подумайте об этом так: как «NSObject», который обеспечивает сравнение по умолчанию, знает, как определено равенство для ваших пользовательских классов? Какие свойства следует учитывать, а какие нет? –

Смежные вопросы