Réponses:
les propriétés ont une signification spécifique dans Objective-C, mais je pense que vous voulez dire quelque chose qui est équivalent à une variable statique? Par exemple, une seule instance pour tous les types de Foo?
Pour déclarer des fonctions de classe dans Objective-C, vous utilisez le préfixe + au lieu de - donc votre implémentation ressemblerait à quelque chose comme:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
.
syntaxe -accessor n'est pas liée aux propriétés dans Objective-C, c'est juste un raccourci compilé pour toute méthode qui renvoie quelque chose sans prendre d'arguments. Dans ce cas, je le préférerais - je préfère personnellement la .
syntaxe pour toute utilisation où le code client a l'intention d'obtenir quelque chose, de ne pas effectuer d'action (même si le code d'implémentation peut créer quelque chose une fois ou effectuer des actions avec effets secondaires) . La .
syntaxe d' utilisation intensive se traduit également par un code plus lisible: la présence de […]
s signifie que quelque chose d'important est en cours lorsque les récupérations utilisent la .
syntaxe à la place.
J'utilise cette solution:
@interface Model
+ (int) value;
+ (void) setValue:(int)val;
@end
@implementation Model
static int value;
+ (int) value
{ @synchronized(self) { return value; } }
+ (void) setValue:(int)val
{ @synchronized(self) { value = val; } }
@end
Et je l'ai trouvé extrêmement utile en remplacement du motif Singleton.
Pour l'utiliser, accédez simplement à vos données avec la notation par points:
Model.value = 1;
NSLog(@"%d = value", Model.value);
self
veut dire à l'intérieur d'une méthode de classe?
self
est l'objet qui a reçu le message . Et puisque les classes sont aussi des objets , dans ce cas, cela self
signifieModel
@synchronized
?
Comme vu dans WWDC 2016 / XCode 8 ( ce qui est nouveau dans la session LLVM @ 5: 05). Les propriétés de classe peuvent être déclarées comme suit
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Notez que les propriétés de classe ne sont jamais synthétisées
@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
static
variable ( ) doit toujours être déclarée et utilisée, et les méthodes implémentées explicitement, telles qu'elles étaient auparavant. La syntaxe des points fonctionnait déjà auparavant également. Dans l'ensemble, cela semble être une affaire plus importante qu'elle ne l'est vraiment.
Si vous recherchez l'équivalent de niveau classe @property
, alors la réponse est "il n'y a rien de tel". Mais rappelez-vous, @property
n'est que du sucre syntaxique, de toute façon; il crée simplement des méthodes d'objet correctement nommées.
Vous voulez créer des méthodes de classe qui accèdent à des variables statiques qui, comme d'autres l'ont dit, n'ont qu'une syntaxe légèrement différente.
UIDevice.currentDevice.identifierForVendor
travaille pour moi.
Voici un moyen sûr de le faire:
// Foo.h
@interface Foo {
}
+(NSDictionary*) dictionary;
// Foo.m
+(NSDictionary*) dictionary
{
static NSDictionary* fooDict = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
// create dict
});
return fooDict;
}
Ces modifications garantissent que fooDict n'est créé qu'une seule fois.
À partir de la documentation Apple : "dispatch_once - Exécute un objet bloc une seule fois pour la durée de vie d'une application."
Initializer element is not a compile-time constant
.
Depuis Xcode 8, Objective-C prend désormais en charge les propriétés de classe:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Comme les propriétés de classe ne sont jamais synthétisées, vous devez écrire votre propre implémentation.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Vous accédez aux propriétés de la classe à l'aide de la syntaxe à points normale sur le nom de la classe:
MyClass.identifier;
Les propriétés ont des valeurs uniquement dans les objets, pas dans les classes.
Si vous devez stocker quelque chose pour tous les objets d'une classe, vous devez utiliser une variable globale. Vous pouvez le cacher en le déclarantstatic
dans le fichier d'implémentation.
Vous pouvez également envisager d'utiliser des relations spécifiques entre vos objets: vous attribuez un rôle de maître à un objet spécifique de votre classe et liez d'autres objets à ce maître. Le maître conservera le dictionnaire comme une simple propriété. Je pense à un arbre comme celui utilisé pour la hiérarchie des vues dans les applications Cocoa.
Une autre option consiste à créer un objet d'une classe dédiée qui est composé à la fois de votre dictionnaire «classe» et d'un ensemble de tous les objets liés à ce dictionnaire. C'est quelque chose comme NSAutoreleasePool
dans Cocoa.
À partir de Xcode 8, vous pouvez utiliser l' attribut de propriété de classe comme l'a répondu Berbie.
Cependant, dans l'implémentation, vous devez définir à la fois le getter de classe et le setter pour la propriété de classe à l'aide d'une variable statique au lieu d'un iVar.
Sample.h
@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end
Sample.m
@implementation Sample
static Sample *_sharedSample;
+ ( Sample *)sharedSample {
if (_sharedSample==nil) {
[Sample setSharedSample:_sharedSample];
}
return _sharedSample;
}
+ (void)setSharedSample:(Sample *)sample {
_sharedSample = [[Sample alloc]init];
}
@end
Si vous avez de nombreuses propriétés de niveau classe, un modèle singleton peut être en ordre. Quelque chose comme ça:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
Et
// Foo.m
#import "Foo.h"
@implementation Foo
static Foo *_singleton = nil;
+ (Foo *)singleton {
if (_singleton == nil) _singleton = [[Foo alloc] init];
return _singleton;
}
@synthesize property1;
@synthesize property2;
@synthesise property3;
@end
Accédez maintenant à vos propriétés au niveau de la classe comme ceci:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
dispatch_once
ici.
[Essayez cette solution, c'est simple] Vous pouvez créer une variable statique dans une classe Swift puis l'appeler à partir de n'importe quelle classe Objective-C.