29 votes

Variables statiques, externes et publiques en Objective-C

Je veux avoir une variable à laquelle je peux accéder n'importe où en important un fichier d'en-tête mais je veux aussi qu'elle soit statique dans le sens où il n'y en a qu'une seule de créée. Dans mon fichier .m, je spécifie

static BOOL LogStuff = NO;

et dans la méthode d'initialisation, j'ai défini la valeur de journalisation :

+ (void)initialize
{
    LogStuff = ... //whatever
}

Cependant, je veux pouvoir accéder à ma variable n'importe où en important le fichier .h. Je veux donc faire quelque chose comme ceci :

static extern BOOL LogStuff;

mais je ne suis pas autorisé à le faire. Est-il possible de faire ce que j'essaie de faire ? Merci

97voto

Adam Rosenfield Points 176408

static en Objective-C ne signifie pas la même chose que static dans une classe C++, dans le contexte des membres de données de classe statiques et des méthodes de classe statiques. En C et en Objective-C, un static variable ou fonction à portée globale signifie que ce symbole a lien interne .

Un lien interne signifie que ce symbole est local à l'objet courant. unité de traduction qui est le fichier source actuel ( .c ou .m ) en cours de compilation et tous les fichiers d'en-tête qu'il inclut récursivement. Ce symbole ne peut pas être référencé à partir d'une unité de traduction différente, et vous pouvez avoir d'autres symboles avec des liens internes dans d'autres unités de traduction avec le même nom.

Ainsi, si vous avez un fichier d'en-tête qui déclare une variable comme étant static chaque fichier source qui inclut cet en-tête reçoit un message séparé toutes les références à cette variable dans un fichier source feront référence à la même variable, mais les références dans des fichiers sources différents feront référence à la variable différents variables.

Si vous voulez avoir une seule variable globale, vous ne pouvez pas l'avoir dans la portée de la classe comme en C++. Une option consiste à créer une variable globale avec lien externe : déclarer la variable avec l'attribut extern dans un fichier d'en-tête, et ensuite dans un définissez-le à l'échelle globale sans la balise extern mot-clé. La liaison interne et la liaison externe s'excluent mutuellement : une variable ne peut pas être déclarée à la fois en tant que extern et static .

Une alternative, comme Panos a suggéré serait d'utiliser une méthode de classe au lieu d'une variable. Cela permet de conserver la fonctionnalité dans la portée de la classe, ce qui est plus logique d'un point de vue sémantique. @private si vous le souhaitez. Cela ajoute une pénalité de performance marginale, mais il est très peu probable que ce soit le goulot d'étranglement de votre application (si vous pensez que c'est le cas, commencez toujours par établir un profil).

3voto

Panos Points 791

Si LogStuff est un champ de classe statique, peut-être pouvez-vous implémenter des getter et setter statiques ?

+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;

3voto

NSResponder Points 14459

Déclarez-le extern BOOL dans votre fichier d'en-tête. Les fichiers qui #import votre en-tête ne sait pas ou ne se soucie pas de savoir si le symbole externe est statique ou non.

1voto

Variable globale séparée (une par fichier source) :

// .h
static NSString * aStatic;

//.m
static NSString * aStatic = @"separate";

Variable globale unique :

// .h
extern NSString * anExtern;

// .m
NSString * anExtern = @"global";

0voto

Volure DarkAngel Points 5916

J'utilise normalement cette disposition pour mes statiques :

NSMutableArray *macroArray;
BOOL keepMacro;

+ (void) startMacro
{
    if (macroArray == nil)
    {
        macroArray = [[NSMutableArray alloc] initWithCapacity:100];
    }

    [macroArray removeAllObjects];
    keepMacro = YES;
}

C'est le startMacro dans mon application. Les deux Bool et le macroArray sont statiques, mais remarquez qu'ils ne sont pas déclarés static ou extern .

Ce n'est peut-être pas la meilleure pratique, mais c'est ce que je fais.

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