NSIndexSet
peut être un peu ennuyant en Objective-C. Contrairement à NSArray
, NSSet
et NSDictionary
, on ne peut pas itérer en utilisant une simple boucle for (a in b)
. C’est parce que contrairement aux autres contenants Objective-C, NSIndexSet
contient des nombres, pas des objets. Depuis Mac OS X 10.6 on peut utiliser un bloc pour itérer sur un NSIndexSet
, mais ce n’est pas toujours idéal : sortir de la boucle est plus compliqué et retourner à partir du bloc ne retourne pas de la fonction parente. Que peut-on faire de mieux ?
Dans un monde idéal, on pourrait écrire ceci (mais malheureusement ça ne marche pas) :
for (NSUInteger index in indexSet)
{
// contenu de la boucle
}
Ce que MFIndexSetForeach
rend possible est ceci :
MFIndexSetForeach(index, indexSet)
{
// contenu de la boucle
}
MFIndexSetForeach
parcourras tous les indexes de l’ensemble. Il remplis un petit tableau d’index à l’aide de la méthode getIndexes:maxCount:inIndexRange:
de NSIndexSet
, parcourt le tableau, puis remplis le tableau à nouveau jusqu’à ce que tous les index soit parcouru. C’est très similaire à la mécanique de for (a in b)
.
Cette boucle se comporte en tout points comme elle doit se comporter : vous pouvez utiliser break
et continue
, et même return
pour sortir de la fonction :
MFIndexSetForeach(index, indexSet)
{
if (index % 33) continue;
if (index % 22) break;
if (index % 11) return YES;
}
Oh, et les accolades sont optionnelles aussi.
Le code généré par la macro est équivalent à ceci :
NSRange _indexRange = NSMakeRange(0, NSUIntegerMax);
for (NSUInteger index,
_bufferIndex = _bufferLength-1,
_indexCount = 0,
_indexBuffer[_bufferLength];
_MFIndexSetForeachNextIndex(
&_bufferIndex, &_indexCount, indexSet, _indexBuffer,
_bufferLength, &_indexRange, &index);
)
{
if (index % 33) continue;
if (index % 22) break;
if (index % 11) return YES;
}
où _MFIndexSetForeachNextIndex
est une courte fonction qui fait tout le travail.
Vous trouverez le code ici : Index Set Foreach