Mise en place NSMutableArray - Quelqu'un peut-il expliquer ce que cet extrait de code fait?
-
16-09-2019 - |
Question
J'ai trouvé ce bout de code sur le net. Elle met en place un NSMutableArray d'une manière que je ne l'ai pas vu auparavant (je suis un newb Obj-C). Quelqu'un peut-il expliquer ce qu'il fait et pourquoi vous le feriez de cette façon? En particulier, la @syncronized, statique et peu signe plus sur la signature de la méthode.
add the following to the .h file:
+(NSMutableArray *)allMySprites;
add the following to he .m file after implementation:
static NSMutableArray * allMySprites = nil;
+(NSMutableArray *)allMySprites {
@synchronized(allMySprites) {
if (allMySprites == nil)
allMySprites = [[NSMutableArray alloc] init];
return allMySprites;
}
return nil;
}
La solution
Ajout aux autres réponses ... le code affiché est erroné. Il devrait être plus comme ceci:
@implementation SpriteManager
+ (NSMutableArray*) allMySprites {
@synchronized(self) {
if (allMySprites == nil) {
allMySprites = [[NSMutableArray alloc] init];
}
}
return allMySprites;
}
@end
Il est absurde de @synchronize sur zéro. Utilisation de l'auto dans une méthode de classe fait référence à la classe et non l'instance. De plus, le code d'origine dans le « néant retour » est inutile.
Une meilleure approche où le @synchronized peut être évité complètement est d'utiliser une méthode d'initialisation de classe:
@implementation SomeClass
+ (void) initialize
{
allMySprites = [[NSMutableArray alloc] init];
}
@end
Les méthodes initialize sont garantis d'être appelé avant la classe est utilisée.
Autres conseils
Le signe de +
indique le procédé est static
par opposition aux méthodes instance
. Cela signifie que la méthode appartient à la classe plutôt que chaque instance d'une classe (comme choses static
en Java et C # ). @synchronized
acquiert un verrou sur l'objet spécifié ( comme déclaration lock
dans C # ). Cela signifie qu'aucun autre thread ne peut entrer dans un bloc de @synchronized
avec cet objet.
Le code dans son ensemble tente d'initialiser une collection de singletons la première fois (quand il est pas encore initialisé) et cache pour une utilisation dans les appels ultérieurs à cette méthode. Le bloc synchronisé crée un section critique pour faire la partie d'initialisation en toute sécurité en cas d'une condition de course où deux threads essaient d'obtenir la valeur à peu près en même temps alors qu'il fait encore l'initialisation.
Il est une implémentation de la design pattern Singleton , essentiellement une façon de faire en sorte que vous seulement avoir une copie de votre MySprites
.
Les détails:
- Le
+
signifie que c'est une méthode de classe - Le
@syncyronize
rend l'accès au thread-safe variablesallMySprites
(il y a quelques mises en garde, mais c'est le résumé d'une ligne) - Je crois que le
static
limite la portée de la variable uniquement au fichier