Почему неявный необязательный параметр не требуется в методе init класса?
Я следую учебному пособию на веб-сайте Рэя Вендерлиха об ARC в Swift, и мне любопытно узнать, почему необязательный необязательный, но не неявный необязательный при создании класса на игровой площадке?
Код детской площадки:
class User {
var name: String
init(name: String) {
self.name = name
print("User \(name) is initialized")
}
deinit {
print("User \(name) is being deallocated")
}
}
class Phone {
let model: String
var owner: User?
init(model: String) {
self.model = model
print("Phone \(model) is initialized")
}
deinit {
print("Phone \(model) is being deallocated")
}
}
do {
let user1 = User(name: "John")
}
let user2 = User.init(name: "Berry")
В классе Phone, если я изменю переменную владельца на неявную необязательную с восклицательным знаком, игровая площадка не выдаст ошибку, однако, если я уберу знак вопроса или не сделаю его необязательным, я получу ошибку.
Не вызывает ли неявное необязательное приложение аварийное завершение работы приложения, если оно не установлено?
Мы ценим любую помощь, чтобы получить четкое представление о том, почему неявное необязательное нормально.
1 ответ
Неявный необязательный параметр все еще является необязательным, поэтому он может быть nil
и это не должно быть установлено во время инициализации. Однако вы все равно получите исключение, если будете обращаться к нему безоговорочно, когда он равен нулю.
Если твой Phone
класс был:
class Phone {
let model: String
var owner: User!
init(model: String) {
self.model = model
print("Phone \(model) is initialized")
}
deinit {
print("Phone \(model) is being deallocated")
}
}
а ты сказал
var aPhone = Phone(model:"iPhone7")
let ownerName = aPhone.owner.name
Тогда вы получите исключение во второй строке, потому что неявно развернутый необязательный nil
, Эта строка эквивалентна написанию let ownerName = aPhone.owner!.name
если owner
были типа User?
,
Неявно развернутые дополнительные параметры очень полезны, когда значение не может быть назначено при инициализации, но значение будет назначено вскоре после этого, так как это устраняет необходимость постоянного развертывания переменной.
Например, неявно развернутые опции часто используются для @IBOutlet
свойства в контроллере представления. Свойство будет установлено процессом загрузки раскадровки, но после инициализации объекта контроллера представления. Поскольку вы знаете, что свойство будет иметь значение к моменту запуска любого вашего кода, использование неявно развернутого необязательного параметра безопасно, и вы избегаете необходимости постоянно разворачивать свойство.
Ваш образец Phone
класс не подходит для неявно развернутых опций; либо простой необязательный (как вы показали), либо обязательный аргумент инициализатора уместен в зависимости от того, могут ли телефоны быть недоступными или нет.