2012-05-14 6 views
18

Nella mia app ho una classe Person con proprietà personId.
Ora ho bisogno di qualche struttura di dati per tenere una serie di esclusive Person oggetti (unica = personId diverso)Obiettivo c - Proprietà oggetto unico NSMutableSet

quindi credo che dovrei usare NSMutableSet come la mia struttura dati, ma come faccio a fare il NSMutableSet confrontare la proprietà personId quando aggiungendo una persona (quindi non aggiungerò la stessa persona più di quelli)?

Il mio obiettivo è avere sempre una collezione di persone uniche (anche se aggiungo due persone con lo stesso id), voglio che NSMutableSet faccia tutto il duro lavoro per me e se aggiungo un la persona che esiste già non la aggiungerà due volte.

risposta

32

È possibile raggiungere questo comprendendo come il confronto è fatto dal NSSet. Quando si aggiunge un nuovo oggetto al set, viene chiamato il metodo isEqual: (è un metodo NSObject) su ciascuno degli elementi del set. Che cosa si può fare è ignorare questo metodo e fornire un confronto personalizzato come questo:

NOTA:

In caso di superamento isEqual: metodo must esclusione hash metodo così

// 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

grazie questo è quello che stavo cercando :) – Eyal

+0

solo una cosa, se la mia personaId è NSString, come dovrei scavalcare il metodo hash? – Eyal

+1

Basta lanciarlo su un int come questo: '[self.personId intValue]'. E per il tuo confronto usa: '[self.personId isEqualToString: anObject.personId]' – Alladinian

0

Non devi preoccuparti di questo quando aggiungi elementi a un array. Finché si aggiunge un oggetto univoco ogni volta, le proprietà dell'oggetto non dovrebbero avere importanza.

Se si è preoccupati di questo e si desidera essere doppiamente sicuri, utilizzare invece NSMutableSet (a meno che non sia necessario mantenere l'ordine di ciascun oggetto).

Aggiornamento

Si potrebbe utilizzare un predicato per controllare che un oggetto con lo stesso valore non esiste prima di aggiungerlo. Funzionerebbe bene con NSMutableArray e 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]; 
} 

pseudocodice molto ruvida, ma si spera di ottenere il succo :)

+0

mio l'obiettivo è avere sempre una collezione di persone uniche (anche se aggiungo due persone con lo stesso id), voglio che NSMutableSet faccia il duro lavoro per me e se sto aggiungendo una persona che già esiste ha vinto aggiungilo due volte .. – Eyal

+0

È possibile utilizzare un predicato per verificare se un oggetto esiste già con lo stesso valore - vedere le mie modifiche. – CaptainRedmuff

+0

NSMutableSet non controllerà automaticamente l'ID della persona. Considererà che due oggetti sono gli stessi solo se in effetti puntano entrambi allo stesso oggetto esatto. Stai meglio con il dizionario come indicato di seguito. Farà la sostituzione di identici personIDs per te. –

4

penso che ciò che si vuole è un NSMutableDictionary, la mappatura del personId all'oggetto Person.

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

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

(non dimenticate di rilasciare dict poi da qualche parte).

Al fine di trovare la classe Person per il specificato personId (12, per esempio), si può semplicemente fare:

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

Nota: che si deve memorizzare sia la chiave e il valore come oggetti (si non è possibile memorizzare tipi primitivi).

+0

per favore guarda ho spiegato di più nella mia domanda – Eyal

+1

@Eyal Penso che la mia risposta farà quello che vuoi; se aggiungi un altro oggetto con lo stesso 'personId', allora il vecchio oggetto' Persona' sarà sostituito. – trojanfoe