Est-il possible d'envoyer un tableau dans Obj-c pour une fonction d'arguments variables?
En python, il est facile de construire un dictionnaire ou un tableau et de le transmettre déballé à une fonction avec des paramètres variables
J'ai ceci:
- (BOOL) executeUpdate:(NSString*)sql, ... {
Et le manuel de la façon de le faire:
[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,
@"hi'", //look! I put in a ', and I'm not escaping it!
[NSString stringWithFormat:@"number %d", i],
[NSNumber numberWithInt:i],
[NSDate date],
[NSNumber numberWithFloat:2.2f]];
Mais je ne peux pas coder en dur les paramètres que je vais appeler, je le souhaite:
NSMutableArray *values = [NSMutableArray array];
for (NSString *fieldName in props) {
..
..
[values addObject : value]
}
[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,??values];
source d'informationauteur mamcx
Vous devez vous connecter pour publier un commentaire.
Malheureusement, non. Objective-C n'a pas d'argument déballage comme vous obtenir dans beaucoup de langues modernes. Il n'est même pas un bon moyen de contourner cela que je l'ai jamais trouvé.
Une partie du problème est que l'Objective-C est essentiellement juste de C. Il n'plusieurs argument en passant avec C varargs, et il n'y a pas de moyen simple de le faire avec varargs. Un pertinents, de SORTE discussion.
Chuck est juste, il n'y a pas de bon argument déballage en Objective-C. Toutefois, pour les méthodes qui nécessitent nul de terminaison (NS_REQUIRES_NIL_TERMINATION), vous pouvez étendre la liste des variables plus grande que ce qui est nécessaire en utilisant un tableau d'accesseur qui renvoie zéro lorsque
index >= count
. C'est certainement l'un hack, mais il fonctionne.Maintenant, vous pouvez utiliser
NSArrayToVariableArgumentsList
où que vous vous attendez à un néant terminée liste d'arguments variable (aussi longtemps que votre tableau est plus petit que 10 éléments). Par exemple:J'ai voulu faire la même chose. Je suis venu avec la suivante, qui fonctionne très bien, compte tenu de certaines contraintes sur les variables d'entrée.
À l'aide de ce qui précède, je peux appeler le suivant avec un NSArray ou avec varargs.
Une autre astuce est d'utiliser les éléments suivants dans le prototype pour le compilateur de vérifier la sentinelle nil afin d'éviter d'éventuelles mauvaises choses. J'ai reçu ceci de la pomme en-têtes...
Il est un bel exemple de comment vous pouvez aller à partir de NSArray à va_list ici (voir "va_list Cacao" et "la Création d'un faux va_list" articles vers le bas):
http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
Voici un teaser ("arguments" est NSArray):
Pas assez de python ou ruby, mais bon...
Vous devriez utiliser les nouvelles FMDB version http://github.com/ccgus/fmdb. C'est la méthode que vous avez besoin de:
Pour accomplir ce que vous voulez, vous devez utiliser le "varargs", en tant que votre méthode utilise, ou vous pouvez passer un tableau de valeurs, quelque chose comme
[db executeUpdate:sql withValues:vals];
puis tirez les valeurs de la méthode. Mais il n'y a pas moyen de faire quelque chose de plus "Pythonic", comme le déballage d'un n-uplet de valeurs, à ladef executeUpdate(sql, *args)
.Malheureusement (Objective-C n'est pas un moyen de le faire. La méthode executeUpdate devraient accepter un NSArray au lieu de la liste d'arguments variable dans ce cas.
Toutefois, si vous savez que le montant des entrées dans le tableau (vous avez le montant de la chaîne dans l'exemple de toute façon), vous pouvez bien sûr faire quelque chose comme
Si executeUpdate est une bibliothèque externe méthode et que la bibliothèque n'offre pas une version de la méthode de l'acceptation d'un NSArray, vous pouvez venir avec votre propre fonction wrapper. La fonction serait de prendre la chaîne de requête et un tableau en argument. Cette fonction serait alors appeler la méthode executeUpdate avec la bonne quantité d'arguments fondés sur la longueur du tableau, quelque chose le long des lignes de
vous pouvez ensuite appeler cette nouvelle fonction comme
Le principal inconvénient de cette solution est que vous avez besoin pour gérer toutes les longueurs possibles de la matrice séparément dans la fonction et il a beaucoup de copier-coller le code.
en outre à robottobor de la solution:
si vous ajoutez la macro suivante:
vous pourrez alors faire une délicate des choses comme: