146 votes

Variables statiques de niveau classe en Objective C

J'ai une classe Film, dont chacune stocke un ID unique. En C#, Java etc., je peux définir un static int currentID et à chaque fois que je définis l'ID, je peux augmenter le currentID et le changement se produit au niveau de la classe et non de l'objet. Cela peut-il être fait en Objective C ? J'ai eu beaucoup de mal à trouver une réponse à cette question.

159voto

Albaregar Points 4440

Description du problème :

  1. Vous voulez que votre ClasseA ait une variable de classe ClasseB.
  2. Vous utilisez Objective-C comme langage de programmation.
  3. Objective-C ne supporte pas les variables de classe comme le fait le C++.

Une alternative :

Simuler le comportement d'une variable de classe à l'aide de fonctionnalités Objective-C

  1. Déclarez/définissez une variable statique dans le fichier classA.m afin qu'elle ne soit accessible que pour les méthodes classA (et tout ce que vous mettez dans classA.m).

  2. Écraser la méthode de classe NSObject initialize pour initialiser une seule fois la variable statique avec une instance de ClassB.

  3. Vous vous demandez sans doute pourquoi je dois écraser la méthode NSObject initialize. La documentation d'Apple sur cette méthode a la réponse : "Le runtime envoie initialize à chaque classe d'un programme exactement une fois, juste avant que la classe, ou toute classe qui en hérite, reçoive son premier message depuis le programme. (Ainsi, la méthode peut ne jamais être invoquée si la classe n'est pas utilisée)".

  4. N'hésitez pas à utiliser la variable statique dans n'importe quelle méthode de classe ou d'instance de ClassA.

Exemple de code :

fichier : classA.m

static ClassB *classVariableName = nil;

@implementation ClassA

...

+(void) initialize
{
    if (! classVariableName)
        classVariableName = [[ClassB alloc] init];
}

+(void) classMethodName
{
    [classVariableName doSomething]; 
}

-(void) instanceMethodName
{
    [classVariableName doSomething]; 
}

...

@end

Références :

  1. Les variables de classe expliquées en comparant les approches Objective-C et C++

37voto

Gonzalo Larralde Points 2180

Si vous ne voulez vraiment pas déclarer une variable globale, il y a une autre option, peut-être pas très orthodoxe :-), mais qui fonctionne... Vous pouvez déclarer une méthode "get&set" comme ceci, avec une variable statique à l'intérieur :

+ (NSString*)testHolder:(NSString*)_test {
    static NSString *test;

    if(_test != nil) {
        if(test != nil)
            [test release];
        test = [_test retain];
    }

    // if(test == nil)
    //     test = @"Initialize the var here if you need to";

    return test;
}

Donc, si vous avez besoin d'obtenir la valeur, il suffit d'appeler :

NSString *testVal = [MyClass testHolder:nil]

Et ensuite, quand tu veux le régler :

[MyClass testHolder:testVal]

Dans le cas où vous voulez être capable de mettre cette pseudo-var statique à nil, vous pouvez déclarer testHolder comme ceci :

+ (NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {
    static NSString *test;

    if(shouldSet) {
        if(test != nil)
            [test release];
        test = [_test retain];
    }

    return test;
}

Et deux méthodes pratiques :

+ (NSString*)test {
    return [MyClass testHolderSet:NO newValue:nil];
}
+ (void)setTest:(NSString*)_test {
    [MyClass testHolderSet:YES newValue:_test];
}

J'espère que cela vous aidera ! Bonne chance.

29voto

pgb Points 17316

Dans votre fichier .m, vous pouvez déclarer une variable comme étant statique :

static ClassName *variableName = nil;

Vous pouvez ensuite l'initialiser sur votre +(void)initialize méthode.

Veuillez noter qu'il s'agit d'une simple variable statique en C et qu'elle n'est pas statique au sens où Java ou C# la considèrent, mais elle donnera des résultats similaires.

16voto

Peter N Lewis Points 12025

Dans votre fichier .m, déclarez une variable globale de fichier :

static int currentID = 1;

puis dans votre routine init, référez-vous à cela :

- (id) init
{
    self = [super init];
    if (self != nil) {
        _myID = currentID++; // not thread safe
    }
    return self;
}

ou s'il doit être modifié à un autre moment (par exemple dans la méthode openConnection), il doit être incrémenté à cet endroit. Rappelez-vous qu'il n'est pas thread safe tel quel, vous devrez faire de la syncronisation (ou mieux encore, utiliser un add atomique) s'il y a des problèmes de threading.

11voto

Tom Dalling Points 10656

Comme pgb l'a dit, il n'y a pas de "variables de classe", seulement des "variables d'instance". La façon objective-c de faire des variables de classe est une variable globale statique à l'intérieur du fichier .m de la classe. Le "static" assure que la variable ne peut pas être utilisée en dehors de ce fichier (c'est-à-dire qu'elle ne peut pas être extern).

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