60 votes

Quelle est la différence entre une constante de chaîne et un littéral de chaîne?

J'apprends Objective-C et Cocoa et je suis tombé sur cette affirmation:

Les frameworks Cocoa s'attendent à ce que les constantes de chaîne globales plutôt que les littéraux de chaîne soient utilisées pour les clés de dictionnaire, les noms de notification et d'exception, ainsi que certains paramètres de méthode prenant des chaînes.

Je n'ai travaillé que dans des langages de niveau supérieur, donc je n'ai jamais eu à examiner autant les détails des chaînes. Quelle est la différence entre une constante de chaîne et un littéral?

84voto

Chris Hanson Points 34485

En Objective-C, la syntaxe @"foo" est immuable, littéral instance de NSString. Il ne fait pas une constante chaîne de caractères à partir d'une chaîne littérale, comme Mike assumer.

Objective-C compilateurs généralement n' stagiaire chaînes littérales dans les unités de compilation, ils fusionnent les utilisations multiples de la même chaîne littérale - et il est possible que l'éditeur de liens pour faire des stage à travers les unités de compilation qui sont directement liés dans un seul binaire. (Depuis, de Cacao fait la distinction entre changeant et immuable des chaînes et des chaînes littérales sont toujours aussi immuable, cela peut être simple et sûre.)

Constante sur les cordes de l'autre main sont généralement déclarée et définie en utilisant la syntaxe ressemble à ceci:

// MyExample.h - declaration, other code references this
extern NSString * const MyExampleNotification;

// MyExample.m - definition, compiled for other code to reference
NSString * const MyExampleNotification = @"MyExampleNotification";

Le point de la syntaxe de l'exercice ici est que vous pouvez faire les utilisations de la chaîne efficace en assurant qu'il n'y a qu'une seule instance de cette chaîne en usage , même dans de multiples cadres (bibliothèques partagées) dans le même espace d'adressage. (Le placement de l' const mot-clé en la matière; il garantit que le pointeur lui-même est garanti d'être constante.)

Lors de la gravure de la mémoire n'est pas aussi important que dans les jours de 25MHz 68030 postes de travail avec 8 mo de RAM, la comparaison de chaînes pour l'égalité peut prendre du temps. Veiller à ce que la plupart du temps, les chaînes sont égales seront également pointeur-l'égalité d'aide.

Dire, par exemple, vous voulez vous abonner à des notifications à partir d'un objet par son nom. Si vous utilisez non constantes chaînes de caractères pour les noms, l' NSNotificationCenter affichage de la notification pourraient finir par faire beaucoup de octet-par-octet de la chaîne des comparaisons lors de la détermination de qui est intéressé par elle. Si la plupart de ces comparaisons sont court-circuitées, car les chaînes comparées ont le même pointeur, cela peut être une grande victoire.

12voto

Jano Points 37593

Quelques définitions

Un littéral est une valeur, qui est immuable, par définition. par exemple: 10
Une constante est en lecture seule variable ou un pointeur. par exemple: const int age = 10;
Une chaîne de caractères littérale est une expression comme @"". Le compilateur va la remplacer par une instance de NSString.
Une constante de chaîne est en lecture seule pointeur NSString. par exemple: NSString *const name = @"John";

Quelques commentaires sur la dernière ligne:

  • C'est un pointeur constant, pas une constante de l'objet1. objc_sendMsg2 ne se soucie pas si vous vous qualifiez l'objet avec l' const. Si vous voulez un objet immuable, vous avez le code que l'immutabilité l'intérieur de l'objet3.
  • Tous @"" expressions sont en effet immuable. Ils sont remplacés4 au moment de la compilation avec les instances de l' NSConstantString, ce qui est une institution spécialisée dans la sous-classe d' NSString avec un fixe, disposition de la mémoire5. Cela explique aussi pourquoi, NSString est le seul objet qui peut être initialisé au moment de la compilation6.

Une chaîne constante serait const NSString* name = @"John"; ce qui est équivalent à NSString const* name= @"John";. Ici, à la fois la syntaxe et le programmeur intention sont mauvais: const <object> "est ignoré et l' NSString instance (NSConstantString) était déjà immuable.

1 Le mot-clé const s'applique s'applique à tout ce qui est immédiatement à sa gauche. Si rien n'est à sa gauche, il s'applique à tout ce qui est immédiatement à sa droite.

2 C'est la fonction que le moteur d'exécution utilise pour envoyer tous les messages en Objective-C, et donc ce que vous pouvez utiliser pour modifier l'état d'un objet.

3 Exemple: en const NSMutableArray *array = [NSMutableArray new]; [array removeAllObjects]; const n'empêche pas la dernière instruction.

4 Le code LLVM qui réécrit l'expression est - RewriteModernObjC::RewriteObjCStringLiteral dans RewriteModernObjC.cpp.

5 voir l' NSConstantString définition, cmd+clic dans Xcode.

6 la Création de compiler les constantes de temps pour les autres classes serait facile, mais il faudrait le compilateur à utiliser spécialisé de la sous-classe. Cela permettrait de casser la compatibilité avec les anciens Objective-C versions.


Retour à votre devis

Le Cacao cadres attendre que la chaîne globale des constantes plutôt que de les littéraux de chaîne sont utilisés pour les clés de dictionnaire, de notification et de exception noms, et certains paramètres de la méthode, qui prennent des chaînes de caractères. Vous devrait toujours privilégier les constantes de chaîne sur les littéraux de chaîne lorsque vous avoir un choix. En utilisant les constantes de chaîne, vous demandez de l'aide compilateur pour vérifier votre orthographe et d'éviter ainsi des erreurs d'exécution.

Il est dit que les littéraux sont sujettes à erreur. Mais cela ne veut pas dire qu'ils sont aussi plus lents. Comparer:

// string literal
[dic objectForKey:@"a"];

// string constant
NSString *const a = @"a";
[dic objectForKey:a];

Dans le deuxième cas, je suis en utilisant les touches avec les pointeurs const, donc au lieu [a isEqualToString:b], je peux le faire (a==b). La mise en œuvre de l' isEqualToString: compare la valeur de hachage, puis exécute la fonction C strcmp, de sorte qu'il est plus lent que de comparer les pointeurs directement. Qui est pourquoi les chaines sont mieux: ils sont plus rapides pour comparer et moins sujette aux erreurs.

Si vous aussi vous voulez votre chaîne constante globale, de faire comme ceci:

// header
extern NSString *const name;
// implementation
NSString *const name = @"john";

3voto

Brad Wilson Points 22910

Nous allons utiliser C++, car mon Objectif C est totalement inexistante.

Si vous placez une chaîne en constante variable:

const std::string mystring = "my string";

Maintenant, quand vous appelez les méthodes, vous utilisez my_string, vous utilisez une constante de chaîne:

someMethod(mystring);

Ou, vous pouvez appeler ces méthodes avec le littéral de chaîne directement:

someMethod("my string");

La raison, sans doute, qu'ils vous encouragent à utiliser des constantes de chaîne est parce que Objective-C ne fait pas "en stage"; que, lorsque vous utilisez la même chaîne de caractères littérale en plusieurs endroits, il est en fait un autre pointeur pointant sur une copie séparée de la chaîne.

Pour les clés de dictionnaire, ce qui fait une énorme différence, parce que si je peux voir les deux pointeurs pointent vers la même chose, c'est beaucoup moins cher que d'avoir à faire à un ensemble de comparaison de chaînes de caractères à assurez-vous que les chaînes ont la même valeur.

Edit: Mike, en C#, les chaînes sont immuables, et les chaînes littérales avec des valeurs identiques toute l'extrémité pointant sur la même chaîne de valeur. J'imagine que c'est vrai pour d'autres langues, qui ont les cordes immuables. En Ruby, qui a mutable cordes, ils offrent un nouveau type de données: les symboles ("foo" vs :foo, où le premier est une mutable chaîne, et le dernier est immuable identificateur souvent utilisé pour les clés de Hachage).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X