0

我有几个 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% 确定它不可能始终为零,那么使用隐式展开的可选项似乎仍然很危险。因此,我正在考虑在某处进行检查,以确保在加载之前实际设置了任何隐式展开的变量。

编辑:它更可能为零的情况是第二个开发人员在几个月内出现并实现使用我的控制器的东西,并且不知道需要在加载之前设置实例变量。虽然我想他们应该更清楚,但这会导致生产崩溃,而这正是我试图避免的。我希望它不可能在不依赖约定的情况下崩溃(并且希望不在许多/所有函数中检查/解包选项)

到目前为止,我发现将检查放入 viewDidLoad() 为时已晚。我已经尝试将它放在 viewWillAppear() 中,但这不适用于 UITableViewControllers 之类的东西,因为它们会在视图尝试出现之前尝试加载数据。

基本问题是,Swift 社区是否已经决定了最佳实践?是否使用选项并处理展开、隐式展开的选项并处理战略位置的 nil 检查、非选项并将 init() 添加到每个控制器?或者有没有更好的解决方案我还没有遇到过?

任何想法/建议将不胜感激。

4

1 回答 1

0

您使用隐式展开的可选选项很好,并且仅仅因为您使用的是隐式展开的选项,没有什么可以阻止您在使用它之前检查选项是否为 nil。

如果变量为 nil,则在函数顶部设置一个保护语句以提前退出。

于 2016-04-07T21:00:03.047 回答