2010-11-17 12 views

Respuesta

20

La enumeración rápida debe producir objetos; dado que un NSIndexSet contiene números escalares (NSUInteger s), no objetos, no, no se puede enumerar rápidamente un conjunto de índices.

Hipotéticamente, podría empaquetarlos en NSNumbers, pero entonces no sería muy rápido.

+1

No me importa el golpe de rendimiento, pero tendrías que retrasar enumerar antes de enumerar rápido, ¿verdad? –

+1

Con punteros etiquetados (en plataformas de 64 bits desde OS X 10.7 e iOS 5), la enumeración rápida de 'NSIndexSet' debería ser bastante rápida. –

22

Un ciclo while debería ser el truco. Incrementa el índice después de usar el índice anterior.

/*int (as commented, unreliable across different platforms)*/ 
NSUInteger currentIndex = [someIndexSet firstIndex]; 
while (currentIndex != NSNotFound) 
{ 
    //use the currentIndex 

    //increment 
    currentIndex = [someIndexSet indexGreaterThanIndex: currentIndex]; 
} 
+2

Los índices válidos pueden exceder el rango de valores representables por 'int', ya que los índices no están firmados. Además, cuando se dirige a una plataforma de 64 bits o compila con 'NS_BUILD_32_LIKE_64' definido, el índice es un valor de 64 bits. Utilice 'NSUInteger' en lugar de' int' para que coincida con el tipo almacenado por 'NSIndexSet' en todas las plataformas. –

+2

@Jeremy W. Sherman: en realidad los índices están efectivamente limitados a los valores que pueden ser representados por un ** NSInteger ** ** positivo porque el valor de retorno "no encontrado" es 'NSNotFound' que es lo mismo que' NSIntegerMax' – JeremyP

+1

@Evan: este ejemplo sigue siendo incorrecto. La comparación en el ciclo while debe estar en contra de 'NSNotFound' * not * -1. – JeremyP

142

En OS X 10.6+ y SDK de iOS 4.0 o superior, puede utilizar el mensaje -enumerateIndexesUsingBlock::

NSIndexSet *idxSet = ... 

[idxSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 
    //... do something with idx 
    // *stop = YES; to stop iteration early 
}]; 
+2

Cambiar NSInteger a NSUInteger – cocoafan

+3

¡Esta es la respuesta correcta! – jaredsinclair

+1

Esta es la respuesta real, ¿puede cambiar? – Jameson

10

Respuesta corta: no. NSIndexSet no se ajusta al <NSFastEnumeration> protocol.

+0

¿qué hay de enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * stop) {} --- ¿no es una enumeración rápida? –

2

Suponiendo que tenemos un ejemplar NSTableView (vamos a llamarlo *tableView), puede eliminar varias filas seleccionadas de la fuente de datos (uhm .. *myMutableArrayDataSource), usando:

[myMutableArrayDataSource removeObjectsAtIndexes:[tableView selectedRowIndexes]]; 

[tableView selectedRowIndexes] devuelve un NSIndexSet. No es necesario que comience a enumerar los índices en el NSIndexSet usted mismo.

+0

Este es un punto impresionante acerca de 'NSMutableArray', gracias. –

+0

Esto no responde realmente a la pregunta, sino que dice "quizás no necesites hacer esa pregunta para empezar. ¿Para qué quieres esta enumeración rápida?" –

Cuestiones relacionadas