Aggiornamento: dal registro modifiche di Swift 2.2 (rilasciato il 21 marzo 2016):
Gli inizializzatori di classe designati dichiarati come failable o throwing possono ora restituire zero o generare un errore, rispettivamente, prima che l'oggetto sia stato completamente inizializzato.
Per Swift 2.1 e versioni precedenti:
Secondo la documentazione di Apple (e l'errore del compilatore), una classe deve inizializzare tutte le sue proprietà memorizzate prima di tornare nil
da un inizializzatore non riuscito:
Per le classi, tuttavia, un inizializzatore non riuscito può attivare un errore di inizializzazione solo dopo che tutte le proprietà memorizzate introdotte da quella classe sono state impostate su un valore iniziale e qualsiasi delega dell'inizializzatore ha avuto luogo.
Nota: in realtà funziona bene per strutture ed enumerazioni, ma non per le classi.
Il modo suggerito per gestire le proprietà archiviate che non possono essere inizializzate prima che l'inizializzatore fallisca è dichiararle come optionals implicitamente scartate.
Esempio dai documenti:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
Nell'esempio precedente, la proprietà name della classe Product è definita come avente un tipo di stringa facoltativo non incluso nel wrapping (String!). Poiché è di un tipo facoltativo, ciò significa che la proprietà name ha un valore predefinito nil prima che le venga assegnato un valore specifico durante l'inizializzazione. Questo valore predefinito di nil a sua volta significa che tutte le proprietà introdotte dalla classe Product hanno un valore iniziale valido. Di conseguenza, l'inizializzatore non riuscito per Product può attivare un errore di inizializzazione all'inizio dell'inizializzatore se viene passata una stringa vuota, prima di assegnare un valore specifico alla proprietà name all'interno dell'inizializzatore.
Nel tuo caso, però, semplicemente definendo userName
come String!
non si risolve l'errore di compilazione perché hai ancora bisogno di preoccuparsi per inizializzare le proprietà sulla vostra classe di base, NSObject
. Fortunatamente, con userName
definito come a String!
, puoi effettivamente chiamare super.init()
prima di te return nil
che avvierà la tua NSObject
classe base e correggerà l'errore di compilazione.
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
parametro booleano che consente al mio inizializzatore di calcolare proprietà che possono o non possono essere create al volo. Ad esempio, sedateCreated
manca una chiave e posso impostare la proprietà al volo perché ilcanSetCalculableProperties
parametro è vero, lo imposto semplicemente alla data corrente.