Se produjo un pequeño problema interesante. Estaba escribiendo un método para filtrar una matriz a los objetos únicos:Conversión de NSArray a NSSet, las instancias de clases personalizadas se transfieren de manera incoherente
- (NSArray*)distinctObjectsByAddress {
NSSet* uniqueSet = [NSSet setWithArray:self];
NSArray* retArray = [uniqueSet allObjects];
return retArray;
}
y escribió una unidad de prueba para comprobar:
- (void)testDistinctObjectsByAddress5 {
Person* adam1 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
Person* adam2 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
testPersonArray = [NSArray arrayWithObjects:adam1,adam2, nil];
NSArray* checkArray = [testPersonArray distinctObjectsByAddress];
STAssertEquals([checkArray count], [testPersonArray count], @"Array %@ counts should match %@ %@",checkArray,adam1,adam2);
}
bastante simple. La parte interesante es que alrededor del 80-90% del tiempo pasa la prueba y de vez en cuando falla porque el método distinctObjectsByAddress
solo devuelve un objeto. Pude rastrearlo hasta la llamada [NSSet setWithArray:self]
pero también he podido verificar que los objetos de dos personas son dos objetos diferentes (al menos tienen una dirección diferente). Supongo que setWithArray:
está haciendo una comparación básica de direcciones, pero no entiendo por qué a veces produce dos objetos como debería y en ocasiones solo produce uno.
Algo que acabo de probar estaba cambiando adam2
para que el nombre y el apellido no fueran exactamente lo mismo que adam1
. Esto parece arreglar el error. ¿Esto apunta a algún tipo de optimización del compilador cuando los objetos son lógicamente iguales?
Supongo que el problema es con Person y cómo implementa los métodos hash e igualdad que usa NSSet. –
Utilizará 'isEqual:' como se define en el protocolo 'NSObject' para comparar objetos; ¿Lo has implementado o 'hash' en' Persona'? – Tommy
Además del problema de hash, no estás probando explícitamente adam1 y adam2 por cero. Si ocasionalmente no se inicia, eso explicaría la falla de la prueba. – bneely