Preparación para la entrevista de iOS 5: solteros

May 04 2023
El patrón singleton es un patrón de diseño que garantiza que una clase tenga solo una instancia y proporciona un punto de acceso global a esa instancia. Esto puede ser útil cuando una clase debe compartirse entre varias partes de una aplicación, pero no es práctico ni deseable crear varias instancias de la clase.

El patrón singleton es un patrón de diseño que garantiza que una clase tenga solo una instancia y proporciona un punto de acceso global a esa instancia. Esto puede ser útil cuando una clase debe compartirse entre varias partes de una aplicación, pero no es práctico ni deseable crear varias instancias de la clase. En iOS, el patrón singleton es un patrón de diseño de uso común.

Preguntas de entrevista

  • ¿Qué es Singleton y cómo se usa en el desarrollo de iOS?
  • ¿Puede explicar el patrón de diseño Singleton y sus ventajas?
  • ¿Cuáles son las formas posibles de evitar múltiples instancias de Singleton en un entorno de subprocesos múltiples?
  • ¿Puede dar un ejemplo de cuándo usaría Singleton en su aplicación iOS?
  • ¿Cómo se prueba Singleton en iOS?

Una preocupación frecuente con los singletons es que a menudo no son seguros para subprocesos. A menudo se utilizan desde varios controladores que acceden a la instancia de singleton simultáneamente.

Debe tener en cuenta dos cosas al crear un singleton

  • La instancia debe crearse de manera segura para subprocesos.
  • Debe marcar el método init de la clase como privado para evitar que se creen más instancias.
  • Durante la inicialización de la instancia singleton.
  • Durante lecturas y escrituras en la instancia.

Para implementar el patrón singleton en Swift, la clase que debe ser singleton se define con la staticpalabra clave, que indica que la clase tiene solo una instancia. Se usa una variable estática para almacenar la instancia de la clase y se usa un método estático para acceder a la instancia. Aquí hay un ejemplo de una clase singleton en 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

ventajas

  • Garantiza que solo se cree una única instancia de una clase, lo que puede ayudar a conservar la memoria y mejorar el rendimiento.
  • Proporciona un punto de acceso global a la instancia de la clase, lo que puede facilitar su uso en el código.
  • Puede ser útil para implementar recursos compartidos, como bases de datos o conexiones de red, que deben compartirse entre diferentes partes de su código.
  • Puede hacer que su código sea difícil de probar y depurar, ya que introduce un estado global que se comparte entre diferentes partes de su código.
  • Dificulta la creación de varias instancias de una clase para realizar pruebas u otros fines.
  • Puede conducir a un acoplamiento estrecho y violar los principios del diseño orientado a objetos.
  • No es una buena opción para ninguna tarea relacionada con la sesión del usuario, ya que es posible que deba destruir y crear un nuevo singleton cuando el usuario cierra la sesión.

Hay una garantía de 1 por cuenta (en lugar de una garantía de uno por aplicación). El acceso no es global (se necesita una sesión de usuario). Similar a singleton, creado con pereza en el primer acceso, la misma instancia siempre se devuelve después. Por ejemplo, MyUserSession, se crea cuando un usuario autenticado inicia una sesión. Debe inyectarse en cualquier código que contenga datos de usuario.