Comment créer un NSString à partir d'une chaîne de format comme @“xxx=%@, yyy=%@” et un NSArray des objets?
Est-il possible de créer un nouveau
NSString à partir d'une chaîne de format comme @"xxx=%@, yyy=%@" et un NSArray des objets?
Dans la classe NSSTring il existe de nombreuses méthodes comme:
- (id)initWithFormat:(NSString *)format arguments:(va_list)argList
- (id)initWithFormat:(NSString *)format locale:(id)locale arguments:(va_list)argList
+ (id)stringWithFormat:(NSString *)format, ...
mais non d'entre eux prend un NSArray comme un argument, et je ne peux pas trouver un moyen de créer une va_list à partir d'un NSArray...
- Utilisé depuis que cette question vraiment se rapporte à de Cacao, n'a pas d'iPhone.
Vous devez vous connecter pour publier un commentaire.
Il n'est effectivement pas difficile de créer une va_list à partir d'un NSArray. Voir Matt Gallagher excellent article sur le sujet.
Voici un NSString catégorie pour ce que vous voulez:
Alors:
Malheureusement, pour 64-bit, la va_list format a changé, de sorte que le code ci-dessus ne fonctionne plus. Et sans doute ne doit pas être utilisé de toute façon étant donné qu'elle dépend du format qui est clairement sous réserve de changement. Il n'existe pas vraiment solide pour créer une va_list, une meilleure solution est tout simplement de limiter le nombre d'arguments à un maximum raisonnable (disons 10) et ensuite appeler stringWithFormat avec les 10 premiers arguments, quelque chose comme ceci:
[arguments getObjects:(id *)argList];
et crachePointer to non-const type 'id' with no explicit ownership
Basé sur cette réponse Automatique de Comptage de Référence (ARC): https://stackoverflow.com/a/8217755/881197
Ajouter une catégorie
NSString
avec la méthode suivante:Une solution qui est venu à mon esprit, c'est que je pouvais créer une méthode qui fonctionne avec un grand nombre d'arguments comme:
Je pourrais aussi ajouter une case pour voir si la chaîne de format a plus de 21 caractères " % " et lancer une exception dans ce cas.
@Chuck est correct sur le fait que vous ne pouvez pas convertir un NSArray en varargs. Cependant, je ne recommande pas la recherche pour le modèle de la
%@
dans la chaîne et de le remplacer à chaque fois. (En remplacement de caractères au moyen d'une chaîne est généralement tout à fait inefficace, et pas une bonne idée si vous pouvez accomplir la même chose de façon différente.) Voici un moyen plus efficace pour créer une chaîne de caractères au format que vous décrivez:J'ai inclus l'autorelease pool pour un bon entretien, depuis un autoreleased chaîne sera créé pour chaque entrée de ce tableau, et la mutable tableau est autoreleased ainsi. Vous pouvez facilement faire cela en une méthode/fonction et revenir
composedString
sans retenue, et de gérer l'autorelease ailleurs dans le code si vous le souhaitez.Cette réponse est buggé. Comme l'a noté, il n'y a pas de solution à ce problème qui est garanti pour fonctionner lorsque de nouvelles plates-formes sont introduits autres que d'utiliser le "tableau de 10 éléments" de la méthode.
La réponse par solidsun fonctionnait bien, jusqu'à ce que je suis allé à compiler avec architecture 64 bits. Cela a provoqué une erreur:
EXC_BAD_ADDRESS type EXC_I386_GPFLT
La solution a été d'utiliser une approche légèrement différente pour le passage de la liste d'arguments de la méthode:
Cela ne fonctionne que pour les tableaux à un seul élément
Il est pas de manière générale pour passer un tableau à une fonction ou une méthode qui utilise des varargs. Dans ce cas particulier, cependant, vous pourriez faux en utilisant quelque chose comme:
EDIT: La accepté de répondre à des réclamations il y a une manière de le faire, mais indépendamment de la fragilité de cette réponse peut sembler, cette approche est beaucoup plus fragile. Elle s'appuie sur la mise en œuvre définies par le comportement (en particulier, la structure d'un
va_list
) qui n'est pas assuré de rester le même. Je maintiens que ma réponse est correcte et ma solution proposée est moins fragile, car elle ne repose que sur les fonctions définies de la langue et de cadres.Pour ceux qui ont besoin d'une solution Swift, voici une extension pour ce faire, dans Swift
Oui, c'est possible. Dans GCC ciblant Mac OS X, au moins,
va_list
est tout simplement un C tableau, de sorte que vous aurez à prendre l'une desid
s, alors dites-le NSArray de le remplir:Vous ne devriez pas compter sur cette nature dans le code qui doit être portable. iPhone les développeurs, c'est une chose que vous devriez certainement de test sur l'appareil.
Testé avec le format et les arguments:
Résultat: xxx=XXX, yyy=YYY dernier composant
Résultat: xxx=XXX, yyy=YYY dernier composant
Résultat: xxx=XXX dernière composante
Résultat: le dernier composant
Résultat: un texte
J'ai trouvé un code sur le web qui prétend que c'est possible, mais je n'ai pas réussi à le faire moi-même, cependant, si vous ne connaissez pas le nombre d'arguments à l'avance, vous avez aussi besoin de construire la chaîne de format dynamiquement, donc je ne vois pas le point.
Vous mieux la construction de la chaîne par l'itération de la matrice.
Vous pourriez trouver la stringByAppendingString: ou stringByAppendingFormat: méthode d'instance à portée de main .
On peut créer une catégorie pour les NSString et de faire une fonction qui reçoit un format, d'un tableau et renvoie la chaîne de caractères à remplacer les objets.
Parce que NSArray est créé lors de l'exécution, nous ne pouvons pas fournir au moment de la compilation des avertissements, mais nous pouvons utiliser NSAssert pour nous dire si le nombre de prescripteurs est à égalité avec le nombre d'objets à l'intérieur de la matrice.
Créé un projet sur Github où cette catégorie peut être trouvé. Également ajouté de Chuck version à l'aide de 'stringByReplacingCharactersInRange:" plus de quelques tests.
À l'aide d'un million d'objets dans un tableau, la version avec "stringByReplacingCharactersInRange:" ne pas l'échelle très bien (attendu environ 2 minutes, puis fermé l'application). À l'aide de la version avec NSMutableString, la fonction fait la chaîne en 4 secondes environ. Les tests ont été effectués à l'aide du simulateur. Avant utilisation, des tests devraient être effectués sur un périphérique réel (utilisation d'un appareil, avec le moins d'specs).
Edit: Sur l'iPhone 5s, la version avec NSMutableString prend 10.471655 s (un million d'objets); sur l'iPhone 5 prend 21.304876 s.
Voici la réponse sans explicitement la création d'un tableau:
Première Chaîne est la chaîne de caractères de mise en forme de la prochaine chaîne de la chaîne à être inséré dans la cible.
Non, vous ne serez pas en mesure de. Argument Variable appels sont résolus au moment de la compilation, et votre NSArray le contenu est seulement au moment de l'exécution.