Почему неявный необязательный параметр не требуется в методе 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 класс не подходит для неявно развернутых опций; либо простой необязательный (как вы показали), либо обязательный аргумент инициализатора уместен в зависимости от того, могут ли телефоны быть недоступными или нет.

Другие вопросы по тегам