Estou tentando elaborar um modelo singleton apropriado para uso no Swift. Até agora, consegui obter um modelo seguro sem thread trabalhando como:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
O agrupamento da instância singleton na estrutura estática deve permitir uma única instância que não colide com instâncias singleton sem esquemas de nomenclatura complexos e deve tornar as coisas bastante privadas. Obviamente, porém, este modelo não é seguro para threads. Então, eu tentei adicionar dispatch_once
à coisa toda:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
static var token: dispatch_once_t = 0
}
dispatch_once(Static.token) { Static.instance = TPScopeManager() }
return Static.instance!
}
}
Mas eu recebo um erro de compilador na dispatch_once
linha:
Não é possível converter o tipo da expressão 'Void' em type '()'
Eu tentei várias variantes diferentes da sintaxe, mas todas parecem ter os mesmos resultados:
dispatch_once(Static.token, { Static.instance = TPScopeManager() })
Qual é o uso adequado do dispatch_once
Swift? Inicialmente, pensei que o problema estava no bloco devido à ()
mensagem de erro, mas quanto mais olho para ele, mais acho que pode ser uma questão de dispatch_once_t
definir corretamente.
@lazy
deve ser thread-safe.
Static.instance = TPScopeManager()
força o tipo de instância. Se você usar algo como Static.instance = self()
um inicializador necessário, a classe de tipo apropriada será gerada. Mesmo assim, e isso é importante, apenas uma vez para todas as instâncias da hierarquia! O primeiro tipo a inicializar é o tipo definido para todas as instâncias. Eu não acho que o objetivo-c se comportou da mesma maneira.