7 votes

Comment sont stockées/récupérées les constantes de chaîne en Objective-C ?

Quelqu'un peut-il expliquer où et comment les constantes de chaîne sont stockées par le compilateur et comment le runtime y accède ?

12voto

Rob Napier Points 92148

D'abord l'obligatoire : vous ne devriez pas vous soucier de la façon dont le compilateur fait ceci ; tout ce qui est basé sur la façon dont le compilateur fait ceci est une confiance dangereuse dans quelque chose qui n'est pas garanti et peut changer en fonction de la façon dont le compilateur optimise. N'écrivez pas de code basé sur ceci. Vraiment. OK, nous avons eu cette sortie de la manière.

Disons que vous avez un code comme celui-ci :

NSString *something = @"I'm a constant";

Le compilateur va générer ceci :

    .section    __TEXT,__cstring,cstring_literals
l_.str:                                 ## @.str
    .asciz   "I'm a constant"

Comme vous le voyez, il est stocké dans la section __TEXT, avec votre code, en tant que littéral cstring. Dans la section __DATA, la constante CFString est stockée comme ceci :

    .section    __DATA,__cfstring
    .align  4                       ## @_unnamed_cfstring_
L__unnamed_cfstring_:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ## 0x7c8
    .space  4
    .quad   l_.str
    .quad   14                      ## 0xe

Tout d'abord, il enregistre le CFType ( CFConstantStringClassReference ). Ensuite, des informations internes sur la chaîne de caractères (est-elle immuable, comment est-elle désallouée, est-elle unicode, etc.), un pointeur vers la cstring, et une longueur (14). Si vous souhaitez obtenir des détails sur la structure, téléchargez les sources CF à partir de opensource.apple.com et regardez à CFString.c . Il explique assez bien l'ensemble du champ "informations internes". (Tirez-les de Snow Leopard ; Apple ne les publie pas dans le cadre d'iOS, mais ce sont les mêmes).

Une deuxième chaîne de constantes ressemblerait à ceci, juste pour montrer comment la dénomination des symboles est faite pour l'assembleur.

    .section    __TEXT,__cstring,cstring_literals
l_.str2:                                ## @.str2
    .asciz   "%@"

    .section    __DATA,__cfstring
    .align  4                       ## @_unnamed_cfstring_3
L__unnamed_cfstring_3:
    .quad   ___CFConstantStringClassReference
    .long   1992                    ## 0x7c8
    .space  4
    .quad   l_.str2
    .quad   2                       ## 0x2

Si vous voulez vous faire une idée plus précise, demandez à Xcode de générer l'assemblage d'un simple fichier et voyez ce qu'il fait. Oh, et bien sûr vous ne devez jamais utiliser cette information car gcc peut changer à tout moment. Mais c'est un bon sujet à creuser.

1voto

Vous devez créer un fichier d'en-tête comme

// Constants.h
extern NSString * const MyFirstConstant;
extern NSString * const MySecondConstant;
//etc.

Vous pouvez inclure ce fichier dans chaque fichier qui utilise les constantes ou dans l'en-tête précompilé du projet.

Vous définissez ces constantes dans un fichier .m comme suit

// Constants.m
NSString * const MyFirstConstant = @"FirstConstant";
NSString * const MySecondConstant = @"SecondConstant";

Constants.m doit être ajouté à la cible de votre application/framework afin qu'il soit lié au produit final.

L'avantage d'utiliser des constantes de type chaîne au lieu de #define L'avantage des constantes de l'UE est que vous pouvez tester l'égalité en utilisant la comparaison de pointeurs ( stringInstance == MyFirstConstant ) qui est beaucoup plus rapide que la comparaison de chaînes de caractères ( [stringInstance isEqualToString:MyFirstConstant] )

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