Domanda

Devo determinare se un oggetto è incluso in una relazione di base di dati di base (che è un NSSET) e sto cercando di decidere quale delle due soluzioni è migliore:

Soluzione 1)

if ([managedObject.items containsObject:itemOfInterest])
    return …

Soluzione 2)

for (NSManagedObject *item in managedObject.items)
    if ([item == itemOfInterest])
        return …

La soluzione 1 è più concisa, ma l'NSSET Class Ref afferma che l'enumerazione rapida funziona meglio dell'Objecenumerator di NSSET. Funziona anche meglio di quanto contiene Object?

È stato utile?

Soluzione

Sceglierei sempre l'opzione 1.

È più conciso, posso dire esattamente cosa stai cercando di fare con il codice e le probabilità è che i contiene Object contengano alcune ottimizzazioni piuttosto eleganti.

Altri suggerimenti

Né. Dovresti usare un NSFetchRequest con un predicato. I tuoi modelli possono accidentalmente criticare l'intera relazione, che è molto costosa e non necessaria solo per verificare se contenga un oggetto. Ci sono modi per stare attenti e non criticare l'intera relazione, ma è fragile (piccoli cambiamenti nella tua ricerca portano a enormi cambiamenti nelle prestazioni) e quindi è meglio avere l'abitudine di usare NSFetchRequest piuttosto che la raccolta per la ricerca. Mi piace impostare il mio fetchLimit A 1 in questi casi, quindi una volta che lo trova, smette di apparire.

Per comodità, potresti voler creare un -containsFoo: Metodo sull'oggetto gestito in modo da non dover scrivere la logica di recupero dappertutto.

Le tue due soluzioni sopra sono sottilmente diverse. Il primo verifica se c'è un oggetto nella raccolta isEqual: a itemOfInterest. La tua seconda soluzione verifica se esiste un oggetto nella raccolta nella stessa posizione di memoria di itemOfInterest. Per oggetti con personalizzazione isEqual: Logica, questi possono restituire risultati diversi. Ciò significa che la soluzione 2 potrebbe essere leggermente più veloce per le raccolte di dati non core, ma è perché stai effettivamente testando una cosa diversa, non a causa dell'enumerazione degli oggetti. (In realtà, questo è vero solo per le piccole collezioni; vedi sotto.)

Perché credi che la soluzione 1 usi -objectEnumerator?

Come sottolinea @james Raybould, in genere non dovresti provare a riscrivere i metodi integrati per motivi di prestazione. Se uno isEqual: La versione della soluzione 2 era più veloce della soluzione 1, non penseresti che Apple avrebbe implementato -containsObject: Utilizzo del codice in Soluzione 2?

In realtà, il sottostante CFSet è implementato come hash, quindi il controllo del contenimento è logaritmico piuttosto che lineare. In generale, per set di grandi dimensioni con funzioni di hash ragionevoli, la soluzione 1 sarà più veloce. Vedere il codice per esso in Cfset.c. Cercare CFSetContainsValue(). L'implementazione di CFSET non è garantita per rimanere uguali, ovviamente, ma è utile per capire come le preoccupazioni delle prestazioni sono generalmente affrontate all'interno del cacao.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top