2010-05-31 12 views
16

Tengo una pregunta simple sobre la codificación de xcode pero no sé por qué las cosas no funcionan como creo. Tengo una matriz de objetos (objetos personalizados). Solo quiero comprobar si este está dentro de la matriz. He utilizado el siguiente código:NSArray containsObject method

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

supongo que la comprobación anterior me va a dar un resultado positivo, pero no lo es. Además, verifiqué si los objetos creados son iguales.

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

En la consola, esto es lo que tengo:

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 

Obviamente, el tempItem está dentro de la gama collection pero no aparece nada cuando uso containsObject: para comprobarlo. ¿Alguien podría darme una dirección, en qué parte estoy equivocado? ¡Muchas gracias!

Respuesta

40

La documentación para [NSArray containsObject:] dice:

Este método determina si unObjeto está presente en el receptor por enviando un IsEqual: mensaje a cada uno de objetos del receptor (y pasando unObjeto como el parámetro a cada isEqual: mensaje).

El problema es que está comparando referencias a objetos en lugar de los valores de los objetos. Para que este ejemplo específico funcione, deberá enviar [collection containsObject:] una instancia de una variable que contenga (por ejemplo, A, B o C), o deberá anular el método .

Esto es lo que su método de isEqual podría ser:

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

Para una mejor aplicación, es posible que desee buscar en este question.

+1

Oh, lo siento, solo un error tipográfico para "Fruta", debería ser "Artículo". ¿Quiere decir comparar objetos de clase personalizados mediante containsObject: no funciona? – Anthony

+2

Funciona, solo se compara por defecto con una referencia a su objeto personalizado. Si quiere hacer 'tempItem' igual a' A' en su ejemplo anterior, necesitará simplemente crear ese método 'isEqual' en su clase. – Senseful

+1

@Anthony, piénselo de esta manera: ¿cómo podría 'NSObject', que proporciona la comparación predeterminada, saber cómo se define la igualdad para sus clases personalizadas? ¿Qué propiedades debería tener en cuenta y cuáles no? –