Atualização: Do Swift 2.2 Change Log (lançado em 21 de março de 2016):
Inicializadores de classe designados declarados como failable ou throwing podem agora retornar nil ou lançar um erro, respectivamente, antes que o objeto tenha sido totalmente inicializado.
Para Swift 2.1 e anterior:
De acordo com a documentação da Apple (e o erro do seu compilador), uma classe deve inicializar todas as suas propriedades armazenadas antes de retornar nil
de um inicializador disponível:
Para classes, entretanto, um inicializador failable pode acionar uma falha de inicialização somente depois que todas as propriedades armazenadas introduzidas por essa classe foram definidas com um valor inicial e qualquer delegação de inicializador ocorreu.
Nota: Na verdade, funciona bem para estruturas e enumerações, mas não para classes.
A maneira sugerida de lidar com propriedades armazenadas que não podem ser inicializadas antes que o inicializador falhe é declará-las como opcionais implicitamente desembrulhados.
Exemplo dos documentos:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
No exemplo acima, a propriedade name da classe Product é definida como tendo um tipo de string opcional desdobrado implicitamente (String!). Por ser de um tipo opcional, isso significa que a propriedade name tem um valor padrão de nil antes de receber um valor específico durante a inicialização. Esse valor padrão de nil, por sua vez, significa que todas as propriedades introduzidas pela classe Product têm um valor inicial válido. Como resultado, o inicializador failable para Product pode acionar uma falha de inicialização no início do inicializador se for passada uma string vazia, antes de atribuir um valor específico à propriedade name dentro do inicializador.
No seu caso, entretanto, simplesmente definir userName
como um String!
não corrige o erro de compilação porque você ainda precisa se preocupar em inicializar as propriedades em sua classe base NSObject
,. Felizmente, com userName
definido como a String!
, você pode realmente chamar super.init()
antes de return nil
que irá iniciar sua NSObject
classe base e corrigir o erro de compilação.
class User: NSObject {
let userName: String!
let isSuperUser: Bool = false
let someDetails: [String]?
init?(dictionary: NSDictionary) {
super.init()
if let value = dictionary["user_name"] as? String {
self.userName = value
}
else {
return nil
}
if let value: Bool = dictionary["super_user"] as? Bool {
self.isSuperUser = value
}
self.someDetails = dictionary["some_details"] as? Array
}
}
canSetCalculableProperties
parâmetro booleano que permite ao meu inicializador calcular propriedades que podem ou não ser criadas instantaneamente. Por exemplo, se umadateCreated
chave estiver faltando e eu puder definir a propriedade imediatamente porque ocanSetCalculableProperties
parâmetro é verdadeiro, apenas defini-lo para a data atual.