2016-04-07 6 views
0
.

У меня есть несколько подклассов 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() для каждого контроллера? Или есть лучшее решение, с которым я еще не сталкивался?

Любые мысли/предложения были бы весьма признательны.

+1

Я использую неявно развернутые опции и тестирование. Вы можете проверить опцию для nil, но что вы собираетесь делать? Возможно, ваше приложение не сможет продолжить, если оно неожиданно исчезло. Вы можете зарегистрировать какое-то сообщение об ошибке, но исключение во время тестирования/разработки более полезно. Контроллер просмотра нельзя перезагрузить, если ваше приложение не перезапущено. iOS может отправить вам предупреждение о низкой памяти, но не будет произвольно удалять вещи из памяти, если только это не уничтожит все ваше приложение; и произойдет только в том случае, когда ваше приложение приостановлено. – Paulw11

+0

Во многих случаях контроллер, о котором идет речь, был перенаправлен и находится поверх стека контроллера навигации, поэтому восстановление для него - это то, чтобы показать предупреждение пользователю о том, что что-то пошло не так , а затем вытащите контроллер из стека.Он не фиксирует какую-либо проблему, из-за которой он попадает в состояние nil, но это не сбой, что является самым важным. – othomas

ответ

0

Ваше использование неявно развернутого опциона является прекрасным, и только потому, что вы используете неявно развернутые опции, вам нечего мешать проверять, не является ли опциональным значение nil перед его использованием.

Установите инструкцию охраны в верхней части ваших функций, чтобы выйти раньше, если переменная равна нулю.

+0

Но для этого требуется установка инструкции охраны в каждой функции ... в этом случае я мог бы также использовать одну и ту же инструкцию охраны для разворачивания необязательного. Я надеялся на лучшую практику, возможно, в одном или двух местах, где ее нужно охранять, и тогда мне не нужно беспокоиться об этом с тех пор. – othomas

+0

Где автомобиль входит в контроллер вида? Что означает, чтобы контроллер просмотра существовал без транспортного средства? Если диспетчер представлений не имеет никакого смысла вообще без автомобиля, то вы должны, вероятно, настроить его таким образом, чтобы транспортное средство было передано для создания контроллера вида. Если имеет смысл иметь контроллер вида без транспортного средства, тогда вы должны явно обращаться с этим случаем, когда его там нет. –

+0

Контроллер обзора не имеет места без транспортного средства. Поэтому я согласен с (на наш взгляд, редким) случаем, когда он может быть nil должен быть явно обработан ... следовательно, цель вопроса в первую очередь: какова наилучшая практика, которую сообщество Swift приняло для этой ситуации? Я знаю, что могу сделать это необязательным и проверять его везде, но это огромная боль, и я предполагаю, что у кого-то появился лучший образец. – othomas