Swift — Patrón SINGLETON
Si… porque lo usábamos antes, lo usamos ahora y lo seguiremos usando, voy a tratar de recrear el snippet de código que nos permita cumplir con el patrón singleton.
SINGLETON:
“El patrón singleton (instancia única en inglés) es un patrón de diseño diseñado para restringir la creación de objetos pertenecientes a una clase o el valor de un tipo a un único objeto.
Su intención consiste en garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.”
Básicamente, lo que tratamos de hacer es mantener una única instancia (de un objeto) compartido por todo el proyecto, y con acceso libre para que pueda ser modificado.
Una de las cuestiones, en SWIFT, es que realizar y/o implementar el patrón SINGLETON se puede hacer de varias maneras… pero como sabemos cual es la mejor?
ANTES — Objective-C
Swift es una evolución natural of Objective-C. Por lo que en Objective-C, así es cómo implementamos el patrón singleton:
#pragma mark — Singleton
+ (Singleton *)sharedClient {
static Singleton *_sharedClient = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedClient = [[self alloc] init];
});
return _sharedClient;
}Pero como mencionamos antes, en SWIFT no tenemos solo una manera, sino podemos llegar a encontrar varias (4 por el momento) de realizar lo mismo:
OPCIÓN 1- TRADUCIRLO
Básicamente, estaremos “traduciendo” lo que antes estaba en obj-c a swift, quedando:
OPCIÓN 1- TRADUCIRLO
Básicamente, estaremos “traduciendo” lo que antes estaba en obj-c a swift, quedando:
class SingletonClass {
class var sharedInstance: SingletonClass {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: SingletonClass? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = SingletonClass()
}
return Static.instance!
}
}OPCION 2 — Swift 1
Este era la versión preliminar en Swift 1, dado que en ese momento las clases no soportaban variables estáticas, sin embargo las estructuras si lo soportaban :D
class SingletonClass {
class var sharedInstance: SingletonClass {
struct Static {
static let instance = SingletonClass()
}
return Static.instance
}
}OPCION 3 — Swift 1.2
En Swift 1.2, se ha ganado especificadores de control de acceso y la capacidad de tener miembros de la clase estática. Esto significaba que no es necesario que tener una variable global del espacio de nombres global y ahora podríamos evitar colisiones de espacio de nombres.
private let sharedSingleton = SingletonClass()
class SingletonClass {
class var sharedInstance: SingletonClass {
return sharedSingleton
}
}OPCION 4 — Una Línea
Actualmente, podemos reducir todo a una simple linea:
class SingletonClass {
static let sharedInstance = SingletonClass()
}AHORA — Swift 3
Sin embargo, luego de mucha investigación hemos optado por una versión que nos permitiera asegurarnos que nuestro init sería privado. Esto permite que nuestros singletons sean realmente únicos y evita la creación de los objetos por fuera de la creación de sus propias instancias de la clase a través de la virtud de control de acceso. Dado que en Swift todos los objetos vienen con un public default como inicializador, es necesario sobreescribirlo y hacerlo privado.
class SingletonClass {
// This init is singleton
private init() { }
// MARK: Shared Instance
static let shared = SingletonClass()
}