cocoa - Compruebe si la instancia NSString está contenida en un NSArray
(3)
Tengo una matriz con un montón de cadenas y quiero verificar si una cierta cadena está contenida en la matriz. Si uso el mensaje containsObject
: en la matriz, obtengo los resultados correctos. ¿Todos los objetos NSString
con la misma cadena apuntan al mismo objeto? ¿O por qué el containsObject
: funciona?
NSArray *stringArray = [NSArray arrayWithObjects:@"1",@"2",@"3",anotherStringValue, nil];
if([stringArray containsObject:@"2"]){
//DO SOMETHING
}
Puede usar containsObject
para encontrar si existe cierta cadena,
NSArray *stringArray = [NSArray arrayWithObjects:@"1",@"2",@"3",anotherStringValue, nil];
if ( [stringArray containsObject: stringToFind] ) {
// if found
} else {
// if not found
}
Sí, las NSStrings codificadas (cadenas literales) (que son cualquier @"..."
en su código fuente) se convierten en cadenas que existen indefinidamente mientras se ejecuta su proceso.
Sin embargo, containsObject:
NSArray containsObject:
methods calls isEqual:
en sus objetos, por lo tanto, incluso una cadena creada dinámicamente como [NSString stringWithFormat:@"%d", 2]
devolvería YES
en su fragmento de muestra.
Esto se debe a que el método isEqual de isEqual:
(o más precisamente isEqualToString:
está implementado para ser consciente del contenido (frente a la comparación de identidades de puntero) y devuelve YES
para cualquier par de cadenas que contengan la misma secuencia de caracteres (en el momento de la comparación) , sin importar cómo y cuándo fueron creados.
Para verificar la identidad (puntero) igual, tendrías que enumerar tu matriz y compararla
NSString *yourString = @"foo";
BOOL identicalStringFound = NO;
for (NSString *someString in stringArray) {
if (someString == yourString) {
identicalStringFound = YES;
break;
}
}
(sin embargo, lo más probable es que no quieras).
O de una manera más conveniente:
BOOL identicalStringFound = [stringArray indexOfObjectIdenticalTo:someString] != NSNotFound;
(Es muy probable que tampoco quieras este).
Resumiendo:
Por lo tanto, la razón por la que obtiene una respuesta positiva de containsObject:
NO es porque las cadenas literales comparten la misma instancia constante, PERO porque containsObject:
por convocatorias de convenciones isEqual:
que es consciente del contenido.
Es posible que desee leer la documentación (breve) para isEqual:
del protocolo NSObject .
containsObject:
realiza una comprobación de valor, no una comprobación de puntero. Utiliza el método isEqual:
definido por NSObject y reemplazado por otros objetos para probar. Por lo tanto, si dos cadenas contienen la misma secuencia de caracteres, se considerarán las mismas.
La distinción entre prueba de puntero y prueba de valor es muy importante en algunos casos. Las cadenas constantes definidas en el código fuente son combinadas por el compilador para que sean el mismo objeto. Sin embargo, las cadenas creadas dinámicamente no son el mismo objeto. Aquí hay un programa de ejemplo que demostrará esto:
int main(int argc, char **argv) {
NSAutoreleasePool *p = [NSAutoreleasePool new];
NSString *constantString = @"1";
NSString *constantString2 = @"1";
NSString *dynamicString = [NSString stringWithFormat:@"%i",1];
NSArray *theArray = [NSArray arrayWithObject:constantString];
if(constantString == constantString2) NSLog(@"constantString == constantString2");
else NSLog(@"constantString != constantString2");
if(constantString == dynamicString) NSLog(@"constantString == dynamicString");
else NSLog(@"constantString != dynamicString");
if([constantString isEqual:dynamicString]) NSLog(@"[constantString isEqual:dynamicString] == YES");
else NSLog(@"[constantString isEqual:dynamicString] == NO");
NSLog(@"theArray contains:/n/tconstantString: %i/n/tconstantString2: %i/n/tdynamicString: %i",
[theArray containsObject:constantString],
[theArray containsObject:constantString2],
[theArray containsObject:dynamicString]);
}
El resultado de este programa es:
2011-04-27 17: 10: 54.686 a.out [41699: 903] constantString == constantString2
2011-04-27 17: 10: 54.705 a.out [41699: 903] constantString! = DynamicString
2011-04-27 17: 10: 54.706 a.out [41699: 903] [constantString isEqual: dynamicString] == YES
2011-04-27 17: 10: 54.706 a.out [41699: 903] theArray contiene:
constanteString: 1
constantString2: 1
dynamicString: 1