MFIndexSetForeach

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;
}

_MFIndexSetForeachNextIndex est une courte fonction qui fait tout le travail.

Vous trouverez le code ici : Index Set Foreach


  • © 2003–2018 Michel Fortin.