Objectif-c variables statiques, externes, publiques
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 a qu'une seule d'entre elles créées. Dans mon .m fichier, je spécifie
static BOOL LogStuff = NO;
et dans la méthode initialize j'ai défini la valeur de journalisation:
+ (void)initialize
{
LogStuff = ... //whatever
}
Cependant, je veux être en mesure d'accéder à ma variable n'importe où par l'importation de la .h fichier donc je veux faire quelque chose comme ceci:
static extern BOOL LogStuff;
mais je n'ai pas le droit de faire ça. Est-ce possible de faire ce que j'essaie de faire? Merci
5 réponses
static
dans Objective-C signifie une chose différente de static
dans une Classe C++, dans le contexte des membres de données de classe statique et des méthodes de classe statique. Dans C et Objectif-C, une variable ou une fonction static
de portée mondiale signifie que ce symbole a liaison interne .
couplage interne signifie que ce symbole est local par rapport au Unité de traduction , qui est le fichier source courant. ( .c
ou .m
) est compilé 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 un lien interne dans d'autres unités de traduction avec le même nom.
donc, si vous avez un fichier d'en-tête déclarant une variable comme static
, chaque fichier source qui inclut cet en-tête obtient un séparé variable globale-toutes les références à ce variable à l'intérieur d'un fichier source se réfère à la même variable, mais les références dans différents fichiers source se réfère à variables différentes .
si vous voulez avoir une seule variable globale, vous ne pouvez pas l'avoir dans la classe scope comme en C++. Une option est de créer une variable globale avec lien externe : déclarer la variable avec le mot-clé extern
dans un fichier d'en-tête, puis dans one fichier source, le définir à portée globale sans le mot-clé extern
. Le lien interne et le lien externe sont mutuellement exclusifs-vous ne pouvez pas avoir une variable déclarée à la fois extern
et static
.
une alternative, comme Panos a suggéré , serait d'utiliser une méthode de classe au lieu d'une variable. Cela maintient la fonctionnalité dans le cadre de la classe, ce qui fait plus de sens sémantiquement, et vous pouvez également le faire @private
si vous le désirez. Il ajoute une pénalité de performance marginale, mais c'est très peu probable d'être le goulot d'étranglement dans votre application (si vous le soupçonnez, toujours profil d'abord).
si LogStuff
est un champ de classe statique, peut-être Pouvez-vous mettre en œuvre getter et setter statiques?
+ (void)setLogStuff:(BOOL)aLogStuff;
+ (BOOL)logStuff;
Déclarer 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 si le symbole externe est statique ou non.
variable globale séparée (une par fichier source):
// .h
static NSString * aStatic;
//.m
static NSString * aStatic = @"separate";
Unique variable globale:
// .h
extern NSString * anExtern;
// .m
NSString * anExtern = @"global";
j'utilise normalement cette disposition pour ma statique:
NSMutableArray *macroArray;
BOOL keepMacro;
+ (void) startMacro
{
if (macroArray == nil)
{
macroArray = [[NSMutableArray alloc] initWithCapacity:100];
}
[macroArray removeAllObjects];
keepMacro = YES;
}
c'est la commande startMacro
dans mon application. Les deux Bool
et macroArray
sont statiques, mais remarquez qu'ils ne sont pas déclarés static
ou extern
.
C'est peut-être pas la meilleure pratique, mais c'est ce que je fais.