Comment créer une classe singleton dans Objective C?
OK appDev, vous trouverez probablement pas mal de techniques différentes pour le faire sur le Web. Cependant, pour le développement d'applications iOS, je pense que le moyen le plus pratique est de procéder comme suit:
Ecrivez votre méthode pour obtenir l’objet singleton. (Recommandation: utilisez dispatch_once
thread et GCD pour cela).
Enveloppez vos méthodes dans une macro et ajoutez-les à votre fichier $Project$-Prefix.pch
.
Appelez la macro d'une ligne chaque fois que vous avez besoin d'un objet singleton pour une classe.
Exemple:
CommonMacros.h :
#define SINGLETON_FOR_CLASS(classname)
+ (id) shared##classname {
static dispatch_once_t pred = 0;
static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
YourProject-Prefix.pch:
...
#import "CommonMacros.h"
...
YourSingletonClass.m:
...
SINGLETON_FOR_CLASS(YourSingletonClass)
...
Consultez ce lien pour obtenir la source d'origine - http://getsetgames.com/2009/08/30/the-objective-c-singleton/
@implementation MySingleton
static MySingleton *_sharedMySingleton = nil;
+(MySingleton *)sharedMySingleton {
@synchronized([MySingleton class]) {
if (!_sharedMySingleton)
_sharedMySingleton = [[self alloc] init];
return _sharedMySingleton;
}
return nil;
}
Je pense que c’est ainsi que nous pourrons vraiment obtenir un comportement singleton:
@interface SampleSingletonClass : NSObject
+ sharedSampleSingletonClass;
@end
@implementation SampleSingletonClass
static SampleSingletonClass *singletonObject = nil;
+ (id) sharedSampleSingletonClass
{
if (! singletonObject) {
singletonObject = [[SampleSingletonClass alloc] init];
}
return singletonObject;
}
- (id)init
{
if (! singletonObject) {
singletonObject = [super init];
// Uncomment the following line to see how many times is the init method of the class is called
// NSLog(@"%s", __PRETTY_FUNCTION__);
}
return singletonObject;
}
@end
Ici, même si on appelle la méthode init à la place du + (id) prévu SampleSingletonClass; méthode, l'objet réel est formé une seule fois tout au long du cycle de vie de l'application.
Ceci est ma façon préférée de le faire:
+ (instancetype)sharedObject {
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
Vous pouvez implémenter une classe singleton dans Objective-C.
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
De:http://www.galloway.me.uk/tutorials/singleton-classes/
Singletons en Objective-C
Un de mes modèles de conception les plus utilisés lors du développement pour iOS est le modèle singleton. C’est un moyen extrêmement puissant de partager des données entre différentes parties de code sans avoir à les transmettre manuellement.
Contexte
Les classes singleton sont un concept important à comprendre car elles présentent un modèle de conception extrêmement utile. Par exemple, UIApplication utilise une méthode appelée sharedApplication qui, lorsqu'elle est appelée de n'importe où, renverra l'instance UIApplication qui concerne l'application en cours d'exécution.
Comment implémenter
Singletone.h
#import <foundation/Foundation.h>
@interface Singleton : NSObject {
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
@end
Singleton.m
#import "Singleton.h"
@implementation Singleton
@synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedManager {
static Singleton *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
@end
Cela définit une variable statique (mais globale pour cette unité de traduction)) appelée sharedMyManager qui est ensuite initialisée une fois et une seule fois dans sharedManager. Pour nous assurer qu’il n’est créé qu’une fois, vous utilisez la méthode dispatch_once de Grand Central Dispatch (GCD). Ceci est thread-safe et entièrement géré par le système d’exploitation pour que vous n’ayez pas à vous en soucier.
Essaye ça
Fichier .h de la classe Singleton
#import <Foundation/Foundation.h>
@interface GlobleDirector : NSObject
+(GlobleDirector*)shareManager;
@end
Fichier .m de la classe Singleton
#import "GlobleDirector.h"
@implementation GlobleDirector
+(GlobleDirector*)shareManager{
static GlobleDirector *sharedInstance=nil;
static dispatch_once_t oncePredecate;
dispatch_once(&oncePredecate,^{
sharedInstance=[[GlobleDirector alloc] init];
});
return sharedInstance;
}
@end
static DBHandler* sDBHandler = nil;
- (id)init
{
self = [super init];
if (self) {
[self checkAndCreateDatabase];
}
return self;
}
+(id)sharedDBHandler
{
@synchronized (self) {
if (sDBHandler == nil) {
sDBHandler = [self new];
}
}
return sDBHandler;
}
#import <Foundation/Foundation.h>
@interface singt : NSObject
+ (id)sharedManager;
@end
#import "singt.h"
@implementation singt
+ (id)sharedManager
{
static singt *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
Je sais qu'il est supposé que les visiteurs savent ce qu'est un singleton, mais pour aider ceux qui ne le font pas, je propose ce petit exemple simple avec des données partagées.
L'objet est utilisé pour partager des instances de classes de données ou des instances de classe.
@interface SharedData : NSObject {
id data;
}
- (void)setData:(id)data_;
- (id)data;
@end
@implementation SharedData
//>> singleton
static SharedData *sharedData=nil;
+ (SharedData*)sharedData {
@synchronized (self) {
if (sharedData==nil) sharedData=[[self alloc]init];
}
return sharedData;
}
//<<
- (void)setData:(id)data_ {
data=data_;
}
- (id)data {
return data;
}
@end
... Le 1er appel (+ sharedData) instancie l'objet en se basant sur la variable statique (locale partagée) qu'il renvoie en tant qu'instance ref. L'appel suivant renvoie uniquement la référence à la variable statique.
Les données peuvent être définies/obtenues à tout moment avec l’accesseur intégré.
Le partage d'un objet entraîne une simplification relative, mais il est possible de traiter "manuellement" par partage de références.
@synchronized est juste nécessaire pour le multithreading. Pour le partage d'instances de classes simples, ce n'est pas nécessaire.
Une explication détaillée ici: http://www.galloway.me.uk/tutorials/singleton-classes/
C'est la bonne façon de créer la classe singleton
mySingletonClass.h
@interface mySingletonClass : NSObject
+ (mySingletonClass*)sharedInstance;
@property (nonatomic, assign)BOOL useToken;
mySingletonClass.m
@implementation mySingletonClass
static mySingletonClass *_sharedInstance = nil;
+ (mySingletonClass*)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
Comment accéder aux propriétés ou méthodes d'une classe singleton dans une classe anothor
une autre classe.m
Bool isTokenValid = [mySingletonClass sharedInstance].useToken;
S'il vous plaît essayer ci-dessous le code.
@implementation AppShared
static AppShared *singletonInstance;
+ (AppShared*)Instance{
if (singletonInstance == nil) {
singletonInstance = [[super alloc] init];
}
return singletonInstance;
}