2010-11-17 5 views

Répondre

20

Le dénombrement rapide doit produire des objets; comme un NSIndexSet contient des nombres scalaires (NSUInteger s), pas des objets, non, vous ne pouvez pas énumérer rapidement un ensemble d'index. Hypothétiquement, cela pourrait les enfermer dans NSNumbers, mais ce ne serait pas très rapide.

+1

Cela ne me dérange pas le coup de performance, mais il faudrait ralentir l'énumération avant d'énumérer rapidement, n'est-ce pas? –

+1

Avec les pointeurs étiquetés (sur les plates-formes 64 bits depuis OS X 10.7 et iOS 5), l'énumération rapide 'NSIndexSet' devrait être assez rapide. –

22

Une boucle while devrait faire l'affaire. Il incrémente l'index après avoir utilisé l'index précédent.

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

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

Les index valides peuvent dépasser la plage de valeurs représentable par 'int', puisque les index ne sont pas signés. En outre, lors du ciblage d'une plate-forme 64 bits ou d'un bâtiment avec le paramètre "NS_BUILD_32_LIKE_64" défini, l'index est une valeur de 64 bits. Utilisez 'NSUInteger' au lieu de' int' pour correspondre au type stocké par 'NSIndexSet' sous toutes les plateformes. –

+2

@Jeremy W. Sherman: en réalité les index sont effectivement limités aux valeurs qui peuvent être représentées par un ** NSInteger ** positif car la valeur de retour "not found" est "NSNotFound" qui est la même que "NSIntegerMax" – JeremyP

+1

@Evan: cet exemple est toujours faux. La comparaison dans la boucle while doit être contre 'NSNotFound' * not * -1. – JeremyP

142

Dans OS X 10.6+ et iOS SDK 4.0+, vous pouvez utiliser le message -enumerateIndexesUsingBlock::

NSIndexSet *idxSet = ... 

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

Changer NSInteger à NSUInteger – cocoafan

+3

Ceci est la bonne réponse! – jaredsinclair

+1

Ceci est la réponse réelle, peut demander un changement? – Jameson

10

Réponse courte: non. NSIndexSet n'est pas conforme à <NSFastEnumeration> protocol.

+0

qu'en est-il d'enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * stop) {} --- cette énumération n'est-elle pas rapide? –

2

Supposons que vous avez une instance NSTableView (appelons-le *tableView), vous pouvez supprimer plusieurs lignes sélectionnées à partir de la source de données (Uhm .. *myMutableArrayDataSource), en utilisant:

[myMutableArrayDataSource removeObjectsAtIndexes:[tableView selectedRowIndexes]]; 

[tableView selectedRowIndexes] retourne un NSIndexSet. Pas besoin de commencer à énumérer sur les index dans le NSIndexSet vous-même.

+0

Ceci est un point génial sur 'NSMutableArray', merci. –

+0

Ce n'est pas vraiment répondre à la question, mais plutôt dire "peut-être que vous n'avez pas besoin de poser cette question pour commencer." Que voulez-vous cette énumération rapide? " –