Je suis nouveau à Objective C et je lis un livre intitulé "Visual Quickstart Guide: Objective-C" par Steven Holzner, Peachpit Press
Dans le chapitre 6: Programmation orientée objet, il y a une section intitulée Utilisation des variables de classe où il écrit:
Vous pouvez créer des variables de classe à utiliser avec vos classes, mais il y a un problème: chaque objet de cette classe partage la même variable, donc si un objet change une variable de classe, cette variable est modifiée pour tous les objets. Vous créez des variables de classe avec le mot clé statique. Les variables de classe sont souvent utiles: par exemple, vous pouvez utiliser une variable de classe pour garder une trace du nombre d'objets d'une classe particulière créés dans un programme. Vous ferez cela dans cette tâche.
Et dit d'entrer le code suivant:
#import <stdio.h>
#import <Foundation/NSObject.h>
@interface TheClass: NSObject
static int count; //error: cannot declare variable inside @interface or @protocol
+(int) getCount;
@end
...
Ce code me donne une erreur dans Xcode 4:
Impossible de déclarer une variable dans @interface ou @protocol
Le livre est-il mauvais ou est-ce que je fais quelque chose de mal?
Vous déclarez la variable statique dans le fichier d'implémentation (.m
fichier). Cela devrait fonctionner:
// TheClass.h
@interface TheClass : NSObject
+ (int)count;
@end
// TheClass.m
static int theCount = 0;
@implementation TheClass
+ (int) count { return theCount; }
@end
Ce n'est pas une variable de classe en soi; Objective-C n'a aucune notion de variable de classe. Cependant, couplé à la méthode de classe pour récupérer cette variable, il fonctionne de manière similaire à une variable de classe. Cependant, c'est vraiment juste une variable statique C qui est accessible par l'implémentation de la classe.
J’ai vu un guide de démarrage rapide visuel sur Unix et il a fait grand bruit. Celui-ci ne semble pas être beaucoup mieux, du moins d'après l'échantillon. La façon correcte de créer une variable de classe dans Objective-C ressemble à ceci:
// Counted.h
@interface Counted : NSObject
+ (NSUInteger) numberOfInstances;
@end
// Counted.m
#import "Counted.h"
static NSUInteger instances = 0;
@implementation Counted
- (id) init {
…
instances++;
…
}
- (void) dealloc {
instances--;
}
+ (NSUInteger) numberOfInstances {
return instances;
}
@end
Il s'agit en fait d'une variable statique, pas d'une vraie variable de classe. Mais ne vous inquiétez pas trop des variables de classe de toute façon, elles sont généralement le signe que vous faites quelque chose de mal. (Je simplifie un peu trop, mais pas beaucoup.)
Si vous cherchez un livre Objective-C décent, lisez celui d'Apple . C'est gratuit et c'est une bonne lecture.
Si la "variable de classe" nécessite plus qu'une initialisation triviale, utilisez dispatch_once
:
@interface Foo ()
+ (Foo *)singleton;
@end
+ (Foo *)singleton {
static Foo *_singleton;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_singleton = [[Foo alloc] init];
});
return _singleton;
}
Vous devez déclarer la variable dans le fichier .m, où la @implementation est placée. Alors,
#import "TheClass.h"
static int count;
@implementation
...
@end
Il est important de noter que Objective-C ne prend pas réellement en charge les variables de classe. Mais vous pouvez les simuler avec des variables statiques, comme nous le faisons ici.