Preparação de entrevista para iOS 5 - Singletons
O padrão singleton é um padrão de design que garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a essa instância. Isso pode ser útil quando uma classe precisa ser compartilhada em várias partes de um aplicativo, mas não é prático ou desejável criar várias instâncias da classe. No iOS, o padrão singleton é um padrão de design comumente usado.
Questões de entrevista
- O que é Singleton e como ele é usado no desenvolvimento iOS?
- Você pode explicar o padrão de projeto Singleton e suas vantagens?
- Quais são as possíveis maneiras de evitar várias instâncias de Singleton em um ambiente multithread?
- Você pode dar um exemplo de quando você usaria Singleton em seu aplicativo iOS?
- Como você testa o Singleton no iOS?
Uma preocupação frequente com singletons é que muitas vezes eles não são thread-safe. Eles são frequentemente usados a partir de vários controladores que acessam a instância singleton simultaneamente.
Você precisa considerar duas coisas ao criar um singleton
- A instância deve ser criada de maneira thread-safe
- Você deve marcar o método init da classe como privado para evitar a criação de mais instâncias
- Durante a inicialização da instância singleton.
- Durante leituras e gravações na instância.
Para implementar o padrão singleton no Swift, a classe que precisa ser um singleton é definida com a static
palavra-chave, que indica que a classe possui apenas uma instância. Uma variável estática é usada para armazenar a instância da classe e um método estático é usado para acessar a instância. Aqui está um exemplo de uma classe singleton em 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
Prós
- Garante que apenas uma única instância de uma classe seja criada, o que pode ajudar a economizar memória e melhorar o desempenho.
- Fornece um ponto de acesso global à instância da classe, o que pode facilitar o uso em seu código.
- Pode ser útil para implementar recursos compartilhados, como bancos de dados ou conexões de rede, que precisam ser compartilhados entre diferentes partes do seu código.
- Pode dificultar o teste e a depuração do seu código, pois introduz um estado global que é compartilhado entre diferentes partes do seu código.
- Torna difícil criar várias instâncias de uma classe para teste ou outros fins.
- Pode levar a um acoplamento rígido e violar os princípios do design orientado a objetos.
- Não é uma boa opção para nenhuma tarefa relacionada à sessão do usuário, pois pode ser necessário destruir e criar um novo singleton quando o usuário fizer logout.
Há uma garantia de 1 por conta (em vez de uma garantia de um por aplicativo). O acesso não é global (você precisa de uma sessão de usuário). Semelhante ao singleton, criado preguiçosamente no primeiro acesso, a mesma instância é sempre retornada posteriormente. Por exemplo MyUserSession, é criado quando um usuário autenticado inicia uma sessão. Deve ser injetado em qualquer código que contenha dados do usuário