Aktualizacja: z dziennika zmian Swift 2.2 (opublikowanego 21 marca 2016 r.):
Wyznaczone inicjatory klas zadeklarowane jako dostępne lub zgłaszające mogą teraz zwracać odpowiednio nil lub zgłaszać błąd, zanim obiekt zostanie w pełni zainicjowany.
Dla Swift 2.1 i starszych:
Zgodnie z dokumentacją Apple (i błędem kompilatora), klasa musi zainicjować wszystkie swoje przechowywane właściwości przed powrotem nilz dostępnego inicjatora:
Jednak w przypadku klas dostępny inicjator może wyzwolić błąd inicjalizacji tylko wtedy, gdy wszystkie przechowywane właściwości wprowadzone przez tę klasę zostały ustawione na wartość początkową i nastąpiło delegowanie inicjatora.
Uwaga: w rzeczywistości działa dobrze w przypadku struktur i wyliczeń, ale nie klas.
Sugerowanym sposobem obsługi przechowywanych właściwości, których nie można zainicjować przed niepowodzeniem inicjatora, jest zadeklarowanie ich jako niejawnie rozpakowanych opcji.
Przykład z dokumentów:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
W powyższym przykładzie właściwość name klasy Product jest zdefiniowana jako posiadająca niejawnie rozpakowany opcjonalny typ ciągu (String!). Ponieważ jest to typ opcjonalny, oznacza to, że właściwość name ma domyślną wartość nil, zanim zostanie przypisana określona wartość podczas inicjalizacji. Ta domyślna wartość zero z kolei oznacza, że wszystkie właściwości wprowadzone przez klasę Product mają prawidłową wartość początkową. W rezultacie dostępny inicjator dla produktu może wyzwolić błąd inicjalizacji na początku inicjatora, jeśli zostanie przekazany pusty ciąg, przed przypisaniem określonej wartości do właściwości name w inicjatorze.
W twoim przypadku, jednak po prostu definiując userNamejako String!nie naprawić błąd kompilacji, ponieważ wciąż trzeba się martwić o inicjowanie właściwości na swojej klasy bazowej NSObject. Na szczęście z userNamedefinicją a String!, możesz zadzwonić super.init()przed tobą, return nilco zainicjuje twoją NSObjectklasę bazową i naprawi błąd kompilacji.
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
}
}
canSetCalculablePropertiesparametr boolowski, który umożliwia mojemu inicjatorowi obliczenie właściwości, które można lub nie można utworzyć w locie. Na przykład, jeślidateCreatedbrakuje klucza i mogę ustawić właściwość w locie, ponieważcanSetCalculablePropertiesparametr ma wartość true, po prostu ustawiam go na bieżącą datę.