L'initialisation d'une variable statique dans Objective-C catégorie
J'ai essayé de créer une variable statique pour stocker un dictionnaire d'images. Malheureusement, la meilleure façon que j'ai pu trouver de l'initialiser à vérifier dans chaque fonction qui a utilisé la variable. Depuis que je suis la création de cette variable à l'intérieur d'une catégorie, je ne peux pas juste de réagir à l'intérieur de l'initialiser. Est-il plus propre façon d'initialisation navigationBarImages?
static NSMutableDictionary *navigationBarImages = NULL;
@implementation UINavigationBar(CustomImage)
//Overrider to draw a custom image
- (void)drawRect:(CGRect)rect
{
if(navigationBarImages==NULL){
navigationBarImages=[[NSMutableDictionary alloc] init];
}
NSString *imageName=[navigationBarImages objectForKey:self];
if (imageName==nil) {
imageName=@"header_bg.png";
}
UIImage *image = [UIImage imageNamed: imageName];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
//Allow the setting of an image for the navigation bar
- (void)setImage:(UIImage*)image
{
if(navigationBarImages==NULL){
navigationBarImages=[[NSMutableDictionary alloc] init];
}
[navigationBarImages setObject:image forKey:self];
}
@end
Je déconseille à l'initialisation d'un Obj-c objet avec des valeurs NULL, vous devez l'initialiser à néant!
alors que je suis d'accord, en réalité, nul est juste NUL jeté comme un objet.
néant est l'équivalent de la valeur NULL pour un pointeur vers un objet. nul et NUL ne devraient pas être interchangeables. La valeur NULL est différemment définie que le néant. nulle est définie comme (id)0. NULL n'est pas.
nshipster.com/nil
alors que je suis d'accord, en réalité, nul est juste NUL jeté comme un objet.
néant est l'équivalent de la valeur NULL pour un pointeur vers un objet. nul et NUL ne devraient pas être interchangeables. La valeur NULL est différemment définie que le néant. nulle est définie comme (id)0. NULL n'est pas.
nshipster.com/nil
OriginalL'auteur Casebash | 2010-01-12
Vous devez vous connecter pour publier un commentaire.
Ces fonction est appelée automatiquement lorsque le programme commence et se termine.
+initializer
.Je ne comprends pas.. Où cela ne va? Écrit comme ça? Et que doit-il arriver?
OriginalL'auteur kennytm
Envisager cette approche,
alors à chaque fois que vous woulde utilisation navigationBarImages, le remplacer par navigationBarImages(), comme ceci:
changement
à
Si l'appel de la fonction de surcharge vous dérange, peut-être utiliser une variable temporaire pour attraper le retour de navigationBarImages(),
L'inconvénient est que une fois que vous avez appelé navigationBarImages(), l'instance de NSMutableDictionary a été créé, puis il va jamais eu la chance de dealloc jusqu'à la fin du programme.
Ce n'est pas tout à fait comme les threads que l'utilisation de
dispatch_once
pour initialiser le dictionnaire. Le code serait préférable d'utiliser:static dispatch_once_t once; static NSMutableDictionary *dict = nil; dispatch_once(&once, ^{ dict = [[NSMutableDictionary alloc] init]; }); return dict;
OriginalL'auteur yehnan
Tous vous avez besoin est de définir vos statique une fois à un point connu avant de l'utiliser. Par exemple, vous pouvez définir une NSApplication délégué et disposez-la dans
-applicationDidFinishLaunching:
Il suffit de définir un programme d'installation autonome de la fonction.
Nope. Cela ne marchera pas. quelque Chose a appeler la fonction de configuration.
Mais c'est ce que je voulais dire, le projet de Loi. Fournir une fonction de configuration, en faire la publicité dans un fichier d'en-tête, et de l'appeler à partir d'
-applicationDidFinishLaunching:
(Par "autonome", je voulais dire "plain ol' C de la fonction.")
OriginalL'auteur Jon Reid
Une option est d'utiliser le C++. Changer l'extension du fichier .mm et remplacer
= NULL
avec[[NSMutableDictionary alloc] init]
.OriginalL'auteur Marcelo Cantos
Vous pouvez ajouter
+initialiser
dans le .m fichier de votre catégorie, vous aurez juste besoin de s'assurer que vous n'êtes pas en brisant une implémentation existante ou vous aurez générale wonkiness. (Évidemment, vous pouvez en être sûr, si vous avez écrit le code, mais avec de la troisième partie du code, ce n'est probablement pas la meilleure approche.)Vous pourriez certainement être sûr que si vous avez écrit la classe, ou vous pouvez utiliser le moteur d'exécution de l'introspection des méthodes ou des approches similaires. J'utilise généralement +initialiser dans ma propre source, je viens de le mettre comme une option. Souvent, il est la meilleure option, mais pas avec les catégories.
Si vous avez écrit la classe, vous n'avez pas besoin de mettre +initialiser dans une catégorie. Si vous n'avez pas l'écrire, vous ne pouvez pas faire confiance que vous ne serez pas en piétinant sur elle dans une future version de la bibliothèque. Mettre +initialiser dans une catégorie de risque serait plus élevé que ce qu'il vaut.
C'est probablement le plus risqué et le plus d'ennuis que ce qu'il vaut dans la plupart des cas, mais je suis en désaccord que vous feriez jamais besoin/envie de mettre
+initialize
dans une catégorie. Par exemple, j'ai peut-être écrit de la bibliothèque/code de la structure, mais qui ne veulent pas la variable statique et d'initialisation dans un projet client. J'essayais juste de fournir une solution de rechange appropriée dans certains cas — pour ne pas se rebeller contre ça... 🙂OriginalL'auteur Quinn Taylor