Actualización: del registro de cambios de Swift 2.2 (publicado el 21 de marzo de 2016):
Los inicializadores de clase designados declarados como fallidos o lanzando ahora pueden devolver nil o arrojar un error, respectivamente, antes de que el objeto se haya inicializado por completo.
Para Swift 2.1 y versiones anteriores:
Según la documentación de Apple (y el error de su compilador), una clase debe inicializar todas sus propiedades almacenadas antes de regresar nil
de un inicializador que falla:
Sin embargo, para las clases, un inicializador que falla puede desencadenar una falla de inicialización solo después de que todas las propiedades almacenadas introducidas por esa clase se hayan establecido en un valor inicial y se haya llevado a cabo cualquier delegación de inicializador.
Nota: En realidad, funciona bien para estructuras y enumeraciones, pero no para clases.
La forma sugerida de manejar las propiedades almacenadas que no se pueden inicializar antes de que falle el inicializador es declararlas como opcionales implícitamente desempaquetadas.
Ejemplo de los documentos:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
En el ejemplo anterior, la propiedad de nombre de la clase Producto se define como si tuviera un tipo de cadena opcional sin envolver implícitamente (¡Cadena!). Debido a que es de un tipo opcional, esto significa que la propiedad del nombre tiene un valor predeterminado de nil antes de que se le asigne un valor específico durante la inicialización. Este valor predeterminado de cero a su vez significa que todas las propiedades introducidas por la clase Producto tienen un valor inicial válido. Como resultado, el inicializador que falla para el Producto puede desencadenar un error de inicialización al comienzo del inicializador si se le pasa una cadena vacía, antes de asignar un valor específico a la propiedad del nombre dentro del inicializador.
En su caso, sin embargo, sólo tiene que definir userName
como un String!
problema no se soluciona el error de compilación, ya que todavía tiene que preocuparse sobre la inicialización de las propiedades de su clase base, NSObject
. Afortunadamente, con userName
definido como a String!
, puede llamar super.init()
antes return nil
que usted, lo que iniciará su NSObject
clase base y solucionará el error de compilación.
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 a mi inicializador calcular propiedades que pueden o no pueden crearse sobre la marcha. Por ejemplo, sidateCreated
falta una clave y puedo establecer la propiedad sobre la marcha porque elcanSetCalculableProperties
parámetro es verdadero, simplemente lo configuro en la fecha actual.