2013-10-09 13 views
5

Ultimamente sto usando enumerateKeysAndObjectsUsingBlock: e oggi ho esitato quando uno dei miei colleghi al posto di lavoro ha sottolineato che questo metodo di enumerazione può essere chiamato da thread separati e il mio codice potrebbe non funzionare come previsto. Ha anche suggerito che dovrei usare l'enumerazione rapida. Il problema è che mi piace molto il enumerateKeysAndObjectsUsingBlock: e non mi piace l'enumerazione veloce a causa della sua natura quando si tratta di dizionario.enumerateKeysAndObjectsUsingBlock: posso essere sicuro che sia chiamato sullo stesso thread?

mio metodo sembrava seguente

- (NSArray *)someMethod 
{ 
    __block NSMutableArray *myArray = [NSMutableArray array]; 

    [self.myDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 
     [myArray addObject:obj]; 
    } 

    return myArray; 
} 

Posso essere sicuro che myArray restituisce sempre i valori attesi (assumendo self.myDictionary non è vuoto) e sarà sempre chiamato sullo stesso thread come il someMethod?

Sono consapevole che esiste un metodo enumerateKeysAndObjectsWithOptions:usingBlock: e che si chiama con l'opzione NSEnumerationConcurrent che eseguirà l'enumerazione contemporaneamente su più thread.

Ma non riesco a trovare alcuna documentazione relativa a enumerateKeysAndObjectsUsingBlock.
Lo stesso si riferisce a enumerateObjectsUsingBlock: utilizzato su array.

+1

Che dire della "natura" dell'enumerazione veloce non ti piace così fortemente che preferiresti usare questo metodo di cui non sei sicuro? –

+0

L'ordine conta qui come immagazzini le cose nella tua matrice all'interno di questo blocco? – Unheilig

+0

Con "natura" intendo chiamare allKeys che le enumera e quindi accede all'oggetto, mentre con l'enumerazione dei blocchi si evita ciò. Blocco: codice più comodo e più facile e forse meno scritto sulla mia estremità. – sumofighter666

risposta

7

Come si osserva, a meno che non si chiami enumerateKeysAndObjectsWithOptions con l'opzione NSEnumerationConcurrent, si può essere certi che non verranno eseguiti contemporaneamente. Per quanto riguarda se la resa non simultanea di enumerateKeysAndObjects viene eseguita sullo stesso thread o meno (tuttavia, scommetto che lo faccia), non importa se non è stata eseguita nella stessa coda perché viene eseguita in modo sincrono con rispetto al thread che hai chiamato il metodo di enumerazione. In conclusione, le preoccupazioni legate al filo del collega sono senza valore.

Vorrei notare, tuttavia, che nei miei test aneddotici, questi metodi di enumerazione sono più lenti dell'enumerazione veloce. Se la velocità è di fondamentale interesse (ad esempio, soprattutto se si utilizzano enormi dizionari/array), è possibile utilizzare un'enumerazione rapida. Nella maggior parte degli scenari, però, la differenza non è materiale.

+1

Sono d'accordo con cosa ha detto @Rob. Vorrei aggiungere che 'enumerateKeysAndObjectsUsingBlock:' chiama effettivamente 'enumerateKeysAndObjectsWithOptions: usingBlock:' internamente passando '0' come parametro' options'. – Hejazi

+0

@Hejazi Come hai saputo/saputo? Si prega di elaborare un po 'di più. Grazie. – Unheilig

+0

@Unheilig Ho scoperto controllando lo stack di chiamate e registri quando il blocco viene eseguito. – Hejazi

Problemi correlati