Préparation aux entretiens iOS 5 - Singletons
Le modèle singleton est un modèle de conception qui garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à cette instance. Cela peut être utile lorsqu'une classe doit être partagée entre plusieurs parties d'une application, mais il n'est ni pratique ni souhaitable de créer plusieurs instances de la classe. Dans iOS, le modèle singleton est un modèle de conception couramment utilisé.
Questions d'entretien
- Qu'est-ce que Singleton et comment est-il utilisé dans le développement iOS ?
- Pouvez-vous expliquer le modèle de conception Singleton et ses avantages ?
- Quels sont les moyens possibles d'empêcher plusieurs instances de Singleton dans un environnement multithread ?
- Pouvez-vous donner un exemple d'utilisation de Singleton dans votre application iOS ?
- Comment testez-vous Singleton dans iOS ?
Une préoccupation fréquente avec les singletons est qu'ils ne sont souvent pas thread-safe. Ils sont souvent utilisés à partir de plusieurs contrôleurs accédant simultanément à l'instance singleton.
Vous devez tenir compte de deux choses lors de la création d'un singleton
- L'instance doit être créée de manière à garantir la sécurité des threads
- Vous devez marquer la méthode init de la classe comme privée pour éviter de créer plus d'instances
- Lors de l'initialisation de l'instance singleton.
- Pendant les lectures et les écritures sur l'instance.
Pour implémenter le modèle singleton dans Swift, la classe qui doit être un singleton est définie avec le static
mot-clé, qui indique que la classe n'a qu'une seule instance. Une variable statique est utilisée pour stocker l'instance de la classe et une méthode statique est utilisée pour accéder à l'instance. Voici un exemple de classe singleton dans Swift
class Singleton {
// Swift guarantees initialization is atomic
// Swift treats the code performing initialization as a critical section
static let shared = Singleton()
// prevents the creation of additional instances of the class.
private init() {}
}
let singleton = Singleton.shared
@implementation MySingleton
// Lazy initializer
+ (instancetype)sharedInstance {
static dispatch_once_t once;
static id sharedInstance;
// The token ensures that init is executed only once in thread safety manner
dispatch_once(&once, ^{
_sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
// Prevent creating new instance of the singleton
- (instancetype)init __attribute__((unavailable("Use +[MyClass sharedInstance] instead")));
+ (instancetype)new __attribute__((unavailable("Use +[MyClass sharedInstance] instead")));
@end
Avantages
- Garantit qu'une seule instance d'une classe est créée, ce qui peut aider à économiser de la mémoire et à améliorer les performances.
- Fournit un point d'accès global à l'instance de la classe, ce qui peut faciliter son utilisation dans votre code.
- Peut être utile pour implémenter des ressources partagées, telles que des bases de données ou des connexions réseau, qui doivent être partagées entre différentes parties de votre code.
- Peut rendre votre code difficile à tester et à déboguer, car il introduit un état global partagé entre différentes parties de votre code.
- Rend difficile la création de plusieurs instances d'une classe à des fins de test ou à d'autres fins.
- Peut conduire à un couplage étroit et violer les principes de la conception orientée objet.
- Pas une bonne option pour les tâches liées à la session utilisateur, car vous devrez peut-être détruire et créer un nouveau singleton lorsque l'utilisateur se déconnecte.
Il y a une garantie de 1 par compte (plutôt qu'une garantie d'un par application). L'accès n'est pas global (vous avez besoin d'une session utilisateur). Semblable à singleton, créé paresseusement lors du premier accès, la même instance est toujours renvoyée par la suite. Par exemple MyUserSession, est créé lorsqu'un utilisateur authentifié démarre une session. Il doit être injecté dans tout code contenant des données utilisateur