2010-05-31 18 views
16

Mam proste pytanie dotyczące kodowania xcode, ale nie wiem, dlaczego rzeczy nie działają tak jak myślę. Mam tablicę obiektów (obiekty niestandardowe). Chcę tylko sprawdzić, czy ten jest w tablicy. Użyłem następującego kodu:NSArray zawiera metodęObject

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"); 
} 

Przypuszczam, że powyższe sprawdzenie da mi pozytywny wynik, ale nie jest. Ponadto sprawdziłem, czy utworzone obiekty są takie same.

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); 
} 

W konsoli, to co mam:

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 

Oczywiście tempItem jest wewnątrz tablicy collection ale nic nie pokazuje się, gdy używam containsObject: aby to sprawdzić. Czy ktokolwiek mógłby mi wskazać kierunek, w którym się mylę? Wielkie dzięki!

Odpowiedz

40

Dokumentacja [NSArray containsObject:] mówi:

Metoda ta określa, czy jakisObiekt występuje w odbiorniku przez wysyłając IsEqual: wiadomość do każdego z obiekty odbiornika (i przechodzącej jakisObiekt jako parametr każdy isEqual: message).

Problem polega na tym, że porównuje się odniesienia do obiektów, a nie wartości obiektów. Aby ten konkretny przykład działał, musisz wysłać [collection containsObject:] instancję zmiennej, którą zawiera (na przykład A, B lub C), lub musisz zastąpić metodę [NSObject isEqual:] w klasie.

To właśnie metoda isEqual może wyglądać następująco:

- (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; 
} 

Dla lepszej realizacji, może warto spojrzeć na ten question.

+1

Przepraszam, tylko literówka dla "owoców", powinna to być "pozycja". Czy masz na myśli porównywanie niestandardowych obiektów klasy przez metodę containsObject: nie działa? – Anthony

+2

To działa, po prostu domyślnie porównuje za pomocą odniesienia do niestandardowego obiektu. Jeśli chcesz, aby 'tempItem' było równe' A' w powyższym przykładzie, musisz po prostu utworzyć na swojej klasie metodę "isEqual". – Senseful

+1

@Anthony, pomyśl o tym w następujący sposób: W jaki sposób 'NSObject', który zapewnia domyślne porównanie, wie, jak definiuje się równość dla twoich niestandardowych klas? Jakie właściwości powinien wziąć pod uwagę, a które nie? –