У меня есть несколько подклассов UIViewController, которым необходимо установить некоторые данные экземпляра, прежде чем они смогут правильно загрузиться.Swift UIViewController. Инициализация переменной экземпляра-подкласса.
Пример: - Примечание. Это надуманный пример, извините, если я пропустил некоторые незначительные детали - строка 2 является единственной частью, действительно необходимой для вопроса.
class VehicleSpecificationsTableViewController: UITableViewController {
var vehicle: Vehicle! // <-- Implicitly unwrapped optional is my current solution
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vehicle.specs.count // <-- Crashes here if the view ever loads/reloads when I'm not expecting it
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("vehicleSpecCell", forIndexPath: indexPath) as? VehicleSpecTableViewCell
cell.spec = vehicle.specs[indexPath.row]
return cell
}
}
Вопрос в том, какой тип переменной следует использовать здесь в качестве наилучшей практики. Я использую опции, но мне больно разворачивать их повсюду, поэтому я конвертирую в неявно развернутые опции, так как я буду устанавливать переменную перед загрузкой представления вообще.
Проблема в том, что я беспокоюсь о том, что контроллер получает перезагрузку в разное время, когда я непосредственно не знаю об этом (после предупреждения о памяти, вращения устройства, пробуждения от фона, любого другого странного случая кромки). Хотя я знаю это, вероятно, не должно быть, это все еще кажется действительно опасным, если использовать неявно развернутую опцию, если я не уверен на 100%, что это невозможно для того, чтобы она всегда была нулевой. Поэтому я подумываю о том, чтобы поместить чек где-нибудь, чтобы убедиться, что любые неявно развернутые переменные фактически установлены перед загрузкой.
EDIT: Более вероятный сценарий, заключающийся в том, что он равен нулю, является вторым разработчиком, появляющимся через несколько месяцев и реализующим что-то, что использует мой контроллер, и не знает, что переменная экземпляра должна быть установлена до того, как она загрузится , Хотя они должны знать лучше, я полагаю, это приведет к сбою в производстве, и именно этого я и стараюсь избежать. Я хочу, чтобы это было невозможно для его отказа, не полагаясь на соглашение (и, надеюсь, не проверять/разворачивать опции во многих/всех функциях)
До сих пор я обнаружил, что положить чек в viewDidLoad() слишком поздно , Я попытался поместить его в viewWillAppear(), но это не работает для таких вещей, как UITableViewControllers, потому что они пытаются загрузить свои данные до того, как появится представление.
Основной вопрос:, имеет ли сообщество Swift лучшее на практике? Используете ли вы опциональные опции и занимаетесь развертыванием, неявно разворачиваемыми опциями и обрабатываете nil-чеки в стратегических местах, без опций и добавляете init() для каждого контроллера? Или есть лучшее решение, с которым я еще не сталкивался?
Любые мысли/предложения были бы весьма признательны.
Я использую неявно развернутые опции и тестирование. Вы можете проверить опцию для nil, но что вы собираетесь делать? Возможно, ваше приложение не сможет продолжить, если оно неожиданно исчезло. Вы можете зарегистрировать какое-то сообщение об ошибке, но исключение во время тестирования/разработки более полезно. Контроллер просмотра нельзя перезагрузить, если ваше приложение не перезапущено. iOS может отправить вам предупреждение о низкой памяти, но не будет произвольно удалять вещи из памяти, если только это не уничтожит все ваше приложение; и произойдет только в том случае, когда ваше приложение приостановлено. – Paulw11
Во многих случаях контроллер, о котором идет речь, был перенаправлен и находится поверх стека контроллера навигации, поэтому восстановление для него - это то, чтобы показать предупреждение пользователю о том, что что-то пошло не так , а затем вытащите контроллер из стека.Он не фиксирует какую-либо проблему, из-за которой он попадает в состояние nil, но это не сбой, что является самым важным. – othomas