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

37
demandé sur JPC 2011-10-04 05:01:27

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).

121
répondu Adam Rosenfield 2017-05-23 12:10:26

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;
4
répondu Panos 2011-10-04 01:14:52

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.

3
répondu NSResponder 2011-10-04 01:16:03

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";
1
répondu SwiftArchitect 2015-07-28 20:50:06

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.

0
répondu The Lazy Coder 2017-11-03 17:04:05