2012-05-14 16 views
18

En mi aplicación tengo una clase Person con la propiedad personId.
Ahora necesito un poco de estructura de datos para contener un montón de Person objetos únicos (unique = personId diferente)Objetivo c - Propiedad de objeto único NSMutableSet

así que supongo que debo usar NSMutableSet como mi estructura de datos, pero ¿cómo puedo hacer el NSMutableSet comparar la propiedad personId cuando agregando una persona (¿así que no agregaré a la misma persona más que a otras)?

Mi objetivo es tener una colección de personas únicas todo el tiempo (incluso si agrego dos personas con la misma identificación), quiero que NSMutableSet haga todo el trabajo duro para mí y si agrego un persona que ya existe no lo agregará dos veces.

Respuesta

32

Puede lograr eso al comprender cómo se realiza la comparación mediante NSSet. Cuando agrega un nuevo objeto al conjunto, se llama al método isEqual: (es un método NSObject) contra cada uno de los elementos del conjunto. Así que lo que puede hacer es reemplazar este método y proporcionar una comparación personalizada así:

NOTA:

Si reemplaza isEqual: método que necesidad anulación hash método, así

// In your Person.m 
- (BOOL)isEqual:(id)anObject 
{ 
    return [self.personId isEqual:anObject.personId]; 
    // If it's an object. Otherwise use a simple comparison like self.personId == anObject.personId 
} 

- (NSUInteger)hash 
{ 
    return self.personId; //Must be a unique unsigned integer 
} 
+0

gracias esto es lo que estaba buscando :) – Eyal

+0

solo una cosa, si mi persona es NSString, ¿cómo debería anular el método hash? – Eyal

+1

Simplemente transfiéralo a un int como este: '[self.personId intValue]'. Y para su comparación use: '[self.personId isEqualToString: anObject.personId]' – Alladinian

0

No debería tener que preocuparse por esto cuando agrega elementos a una matriz. Siempre que agregue un objeto único cada vez, las propiedades del objeto no deberían importar.

Si le preocupa esto y desea estar doblemente seguro, utilice NSMutableSet en su lugar (a menos que necesite mantener el orden de cada objeto).

actualización

Se puede usar un predicado para comprobar que un objeto con el mismo valor no existe antes de añadirla. Esto funcionaría bien con NSMutableArray y NSMutableSet.

//create array 
NSMutableArray *array = [[NSMutableArray alloc] init]; 

//create person 
Person *newPerson = [[Person alloc] init]; 

//add person 
[array addObject:newPerson] 

//check new object exists 
if([[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"personID == %@", [newPerson personID]]] count] == 0) 
{ 
    //add object 
    [array addObject:newPerson]; 
} 

pseudocódigo muy duro, pero es de esperar que obtiene la esencia :)

+0

Mi El objetivo es tener una colección de personas únicas todo el tiempo (incluso si agrego dos personas con la misma identificación), quiero que NSMutableSet haga el trabajo duro para mí y si agrego una persona que ya existe, ganó. no lo agregue dos veces .. – Eyal

+0

Puede usar un predicado para verificar si un objeto ya existe con el mismo valor - vea mis ediciones. – CaptainRedmuff

+0

NSMutableSet no verificará automáticamente la identificación de la persona. Considerará que dos objetos son iguales solo si de hecho ambos apuntan a los mismos objetos exactos. Estás mejor con el diccionario como se indica a continuación. Hará el reemplazo de identidades personales idénticas para usted. –

4

creo que lo que quiere es un NSMutableDictionary, la cartografía de la personId al objeto Person.

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 

Person *person = something; 
[dict setObject:personObj forKey:[NSNumber numberWithInt:[person personId]]]; 
... etc ... 

(no se olvide de liberar dict más adelante en alguna parte).

Con el fin de encontrar la clase Person para la personId especificado (12, por ejemplo), sólo tiene que hacer:

Person *person = [dict objectForKey:[NSNumber numberWithInt:12]]; 

Nota: que hay que almacenar la clave y el valor como objetos (se no puede almacenar tipos primitivos).

+0

mira, expliqué más en mi pregunta – Eyal

+1

@Eyal Creo que mi respuesta hará lo que quieras; si agrega otro objeto con el mismo 'personId' entonces se reemplazará el antiguo objeto' Persona '. – trojanfoe

Cuestiones relacionadas