2010-05-31 11 views
16

J'ai une question simple concernant le codage xcode, mais je ne sais pas pourquoi les choses ne fonctionnent pas comme je le pense. J'ai un tableau d'objets (objets personnalisés). Je veux juste vérifier si celui-ci est dans le tableau. J'ai utilisé le code suivant:NSArray containsObject méthode

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

Je suppose que la vérification ci-dessus me donnera un résultat positif mais ce n'est pas le cas. En outre, j'ai vérifié si les objets créés sont les mêmes.

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

Dans la console, ce que je suis:

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 

Il est évident que le tempItem est à l'intérieur du tableau collection mais rien ne montre quand je l'utilise containsObject: pour le vérifier. Quelqu'un pourrait-il me dire dans quelle direction je me trompe? Merci beaucoup!

Répondre

40

La documentation de [NSArray containsObject:] dit:

Cette méthode permet de déterminer si anObject est présente dans le récepteur en envoyant un isEqual: message à chacun des objets du récepteur (et passant anObject en tant que paramètre à chaque estEqual: message).

Le problème est que vous comparez des références aux objets plutôt qu'aux valeurs des objets. Pour que cet exemple spécifique fonctionne, vous devez envoyer une instance de la variable [collection containsObject:] (par exemple, A, B ou C), ou vous devez remplacer la méthode [NSObject isEqual:] dans votre classe Item.

C'est ce que votre méthode isEqual pourrait ressembler à:

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

Pour une meilleure mise en œuvre, vous voudrez peut-être regarder ce question.

+1

Oh, désolé, juste une faute de frappe pour "Fruit", il devrait être "Item". Voulez-vous dire comparer des objets de classe personnalisés par containsObject: ne fonctionne pas? – Anthony

+2

Cela fonctionne, ce n'est qu'une comparaison par défaut avec une référence à votre objet personnalisé. Si vous voulez rendre 'tempItem' égal à' A' dans votre exemple ci-dessus, vous devrez simplement créer cette méthode 'isEqual' sur votre classe. – Senseful

+1

@Anthony, pensez-y de la façon suivante: Comment 'NSObject', qui fournit la comparaison par défaut, peut-il savoir comment l'égalité est définie pour vos classes personnalisées? Quelles propriétés devraient-elles prendre en considération et lesquelles ne le sont pas? –