Оновлення: З журналу змін Swift 2.2 (вийшов 21 березня 2016 р.):
Позначені ініціалізатори класу, оголошені як недоступні або кинуті, тепер можуть повернути нуль або випустити помилку відповідно до того, як об'єкт буде повністю ініціалізований.
Для Swift 2.1 та новіших версій:
Відповідно до документації Apple (та вашої помилки компілятора), клас повинен ініціалізувати всі збережені властивості перед поверненням nil
із недоступного ініціалізатора:
Для класів, однак, недоступний ініціалізатор може викликати збій ініціалізації лише після того, як всі збережені властивості, введені цим класом, будуть встановлені на початкове значення і відбудеться будь-яке делегування ініціалізатора.
Примітка. Це насправді добре працює для структур та перерахувань, тільки не для класів.
Запропонований спосіб обробки збережених властивостей, які неможливо ініціалізувати до відмови ініціалізатора, - це оголосити їх як неявно розгорнуті необов'язкові.
Приклад із документів:
class Product {
let name: String!
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
}
У наведеному вище прикладі властивість імені класу Product визначається як неявно розпакований необов'язковий тип рядка (String!). Оскільки це необов'язковий тип, це означає, що властивість імені має значення за замовчуванням нуль, перш ніж йому буде присвоєно конкретне значення під час ініціалізації. Це значення за замовчуванням нуля в свою чергу означає, що всі властивості, введені класом Product, мають дійсне початкове значення. Як результат, недоступний ініціалізатор для Продукту може викликати збій ініціалізації на початку ініціалізатора, якщо він передається порожнім рядком, перш ніж присвоїти певне значення властивості імені в ініціалізаторі.
У вашому випадку, однак, просто визначаючи , userName
як String!
не виправити помилку компіляції , тому що вам все ще потрібно турбуватися про ініціалізації властивостей на вашому базовому класі NSObject
. На щастя, з userName
визначеним як a String!
, ви можете насправді зателефонувати super.init()
перед вами, return nil
що запустить ваш NSObject
базовий клас та виправить помилку компіляції.
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
булевий параметр, що дозволяє моєму ініціалізатору обчислювати властивості, які можна або не можна створити під час руху. Наприклад, якщоdateCreated
ключ відсутній, і я можу встановити властивість на льоту, тому щоcanSetCalculableProperties
параметр true, я просто встановив його на поточну дату.