Index Set Foreach

Téléchargement

MFIndexSetForeach 1.0 (2 Ko)
Première version. 12 décembre 2011.

Introduction

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.

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 utilise la méthode getIndexes:maxCount:inIndexRange: de NSIndexSet pour remplir un petit tableau d’index, parcourt le tableau puis remplis le tableau à nouveau jusqu’à ce qu’on ait parcouru tous les index. 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.

Comment l’utiliser

MFIndexSetForeach est une macro dans un fichier d’entête du même nom. Ajoutez simplement le fichier “MFIndexSetForeach.h” à votre projet, puis importez le l’entête là où vous avez besoin de la boucle:

#import "MFIndexSetForeach.h"

Et c’est tout.

Comment ça marche?

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. Le vrai code généré utilise des noms de variables plus spéciaux pour éviter les conflits.

Licence

MFIndexSetForeach est disponible sous les termes de la licence Boost Software License 1.0.

Historique

Index Set Foreach 1.0


  • © 2003–2018 Michel Fortin.