2011-03-25 3 views
0

Je veux avoir un objet initialisé dans le délégué et je veux pouvoir utiliser cet objet n'importe où sur les contrôleurs de vue (ne dépend pas de la vue à laquelle je suis actuellement). Je devine que la solution à ce serait d'avoir une classe singleton, jusqu'à présent, je donne les résultats suivants:Classe singleton dans l'objectif-C

@interface LocationManager : NSObject <CLLocationManagerDelegate>{ 
    NSDate *enter; 
    NSDate *exit; 
    CLLocationManager * manager; 

} 

@property (nonatomic, retain) NSDate * enter; 
@property (nonatomic, retain) NSDate * exit; 

- (BOOL)registerRegionWithLatitude:(double)latitude andLongitude:(double)longitude; 
+ (LocationManager *)instance; 

@end 


#import "LocationManager.h" 

@implementation LocationManager 
@synthesize enter; 
@synthesize exit; 

#pragma mark - CLLocationManager delegate 
static LocationManager *gInstance = NULL; 


+ (LocationManager *)instance 
{ 
    @synchronized(self) 
    { 
     if (gInstance == NULL) 
      gInstance = [[self alloc] init]; 
    } 
    return(gInstance); 
} 

@end 

Est-ce exact? Donc, tout ce que j'ai besoin de faire pour y accéder est juste d'appeler instance? A l'intérieur de LocationManager, je veux aussi avoir un seul CLLocationManager, appelé manager. Cependant, où dois-je l'initialiser pour n'en avoir qu'un? Puis-je faire ce qui suit? La plupart des autres exemples singleton Nous ne connaissons aucune variables dans la classe, de sorte que c'est là que je me suis embrouillé

+ (LocationManager *)sharedLocationManager 
{ 
    @synchronized(self) 
    { 
     if (lm == NULL){ 
      lm = [[self alloc] init]; 
      lm.manager = [[CLLocationManager alloc] init]; 
      lm.manager.delegate = lm; 
     } 
    } 
    return(lm); 
} 
+0

googler "objective-c singleton" révèle beaucoup des milliers de hits. –

+0

Je le nommer 'sharedLocationManager' au lieu de' instance'. Apple les nomme ainsi (sauf pour NSNull et NSUserDefaults, mais ils sont spéciaux). –

Répondre

1

En gros - oui.
Juste quelques petites choses:
static LocationManager *gInstance = NULL;
au lieu de NULL, vous devez utiliser nil, il est une convention en Objective-C. Vous devez également remplacer alloc, new, copyWithZone: et mutableCopyWithZone:. De Buck/Yacktman: "Cocoa Design Patterns", p. 153:

+ (id)hiddenAlloc 
{ 
    return [super alloc]; 
} 

+ (id)new 
{ 
    return [self alloc]; 
} 

+ (id)allocWithZone:(NSZone *)zone 
{ 
    return [[self sharedInstance] retain]; 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    [self retain]; 
    return self; 
} 

- (id)mutableCopyWithZone:(NSZone *)zone 
{ 
    return [self copyWithZone:zone]; 
} 

De cette façon, votre objet singleton ne peut pas être copié. Vous devez appeler hiddenAlloc à partir de votre méthode instance (en passant, la méthode pour accéder à un objet Singleton est souvent appelée sharedInstance dans Objective-C).

+0

que diriez-vous de ce CLLocationManager? – aherlambang

+1

deux choses: puisque 'alloc' appelle simplement' allocWithZone: ', vous n'avez pas besoin de les remplacer tous les deux. 'allocWithZone:' devrait simplement renvoyer l'instance singleton (conservée bien sûr) de sorte que si vous essayez d'allouer/init une nouvelle instance, vous récupérez simplement le singleton. –

+0

la seule chose que je suis confus est d'avoir une instance de CLLocationManager ainsi dans cette classe singleton .. – aherlambang

0

Pour les autres styles singleton avec leurs avantages et inconvénients, consultez this question.

Personnellement, je préfère ce style (copié à partir de l'une des réponses sur ce lien):

static MySingleton *sharedSingleton; 

+ (void)initialize 
{ 
    static BOOL initialized = NO; 
    if(!initialized) 
    { 
     initialized = YES; 
     sharedSingleton = [[MySingleton alloc] init]; 
    } 
} 
+0

Le seul inconvénient avec votre réponse est, ce ne sera pas exactement "chargement paresseux". Puisque même si une méthode de classe pour MySingleton est appelée, l'objet sharedInstance sera créé immédiatement. – rishabh

+0

Que ce soit ou non un "inconvénient" dépend de vos besoins. Au moins pour la question initiale "chargement paresseux" n'a pas été déclaré comme une exigence. –

0

En fait, il y a une méthode éprouvée et vraie pour créer singletons déjà. Téléchargez le fichier SynthesizeSingleton.h (à partir d'un Cocoa with Love article). Il contient une quantité massive de code pré-processeur qui va générer n'importe quel singleton pour vous. Hit l'article pour plus de détails.

0

Puisque la méthode d'usine "instance" est une méthode de niveau de classe, le bloc @synchronized doit être @synchronized ([classe LocationManager]) { //}

+0

'self' dans une méthode de classe fait référence à la classe, de sorte que le code original fonctionne comme prévu, au moins à cet égard. – zoul

+1

Il existe déjà une classe singleton dans votre code, la classe AppDelegate. Vous devriez idéalement éviter de créer un singleton, à moins que ce ne soit explicitement requis. Probablement, dans votre cas, le code du gestionnaire d'emplacement peut être simplement défini dans AppDelegat, et les coordonnées doivent être définies comme propriété dans la classe AppDelegate. – rishabh