iOS Interview Prep 5 - Singleton

May 04 2023
Il modello singleton è un modello di progettazione che garantisce che una classe abbia una sola istanza e fornisce un punto di accesso globale a tale istanza. Questo può essere utile quando una classe deve essere condivisa tra più parti di un'app, ma non è pratico o desiderabile creare più istanze della classe.

Il modello singleton è un modello di progettazione che garantisce che una classe abbia una sola istanza e fornisce un punto di accesso globale a tale istanza. Questo può essere utile quando una classe deve essere condivisa tra più parti di un'app, ma non è pratico o desiderabile creare più istanze della classe. In iOS, il modello singleton è un modello di progettazione comunemente utilizzato.

Domande di un'intervista

  • Cos'è Singleton e come viene utilizzato nello sviluppo iOS?
  • Puoi spiegare il modello di progettazione Singleton e i suoi vantaggi?
  • Quali sono i modi possibili per impedire più istanze di Singleton in un ambiente multithread?
  • Puoi fare un esempio di quando useresti Singleton nella tua app iOS?
  • Come si testa Singleton in iOS?

Una preoccupazione frequente con i singleton è che spesso non sono thread-safe. Sono spesso utilizzati da più controller che accedono simultaneamente all'istanza singleton.

Devi considerare due cose quando crei un singleton

  • L'istanza deve essere creata in modo thread safe
  • È necessario contrassegnare il metodo init della classe come privato per impedire la creazione di più istanze
  • Durante l'inizializzazione dell'istanza singleton.
  • Durante le letture e le scritture nell'istanza.

Per implementare il modello singleton in Swift, la classe che deve essere un singleton viene definita con la staticparola chiave, che indica che la classe ha una sola istanza. Una variabile statica viene utilizzata per archiviare l'istanza della classe e un metodo statico viene utilizzato per accedere all'istanza. Ecco un esempio di una classe singleton in 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

Professionisti

  • Assicura che venga creata solo una singola istanza di una classe, che può aiutare a conservare la memoria e migliorare le prestazioni.
  • Fornisce un punto di accesso globale all'istanza della classe, che può semplificarne l'utilizzo nel codice.
  • Può essere utile per implementare risorse condivise, come database o connessioni di rete, che devono essere condivise tra diverse parti del codice.
  • Può rendere difficile il test e il debug del codice, in quanto introduce uno stato globale condiviso tra diverse parti del codice.
  • Rende difficile la creazione di più istanze di una classe per test o altri scopi.
  • Può portare a un accoppiamento stretto e violare i principi della progettazione orientata agli oggetti.
  • Non è una buona opzione per qualsiasi attività relativa alla sessione utente, poiché potrebbe essere necessario distruggere e creare un nuovo singleton quando l'utente si disconnette.

C'è una garanzia di 1 per account (anziché una garanzia di uno per app). L'accesso non è globale (è necessaria una sessione utente). Simile a singleton, creato pigramente al primo accesso, la stessa istanza viene sempre restituita in seguito. Ad esempio MyUserSession, viene creato quando un utente autenticato inizia una sessione. Deve essere inserito in qualsiasi codice che contenga dati utente