我有几个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%确定它是不可能的,那么使用隐式展开的选项似乎仍然非常危险在任何时候都是零。所以我想在某个地方放置一个支票,以确保在加载之前实际设置任何隐式展开的变量。
编辑:更可能的情况是它是nil是第二个开发人员在几个月内出现并实现使用我的控制器的东西,并且不知道实例变量需要在加载之前设置。虽然我认为他们应该知道更好,但这会导致生产崩溃,而这正是我试图避免的。我希望它不可能在不依赖约定的情况下崩溃(并且希望不在许多/所有函数中检查/解包选项)
到目前为止,我发现将支票放入viewDidLoad()为时已晚。我已经尝试将它放在viewWillAppear()中,但这对UITableViewControllers之类的东西不起作用,因为它们试图在视图试图出现之前加载它们的数据。
基本问题,Swift社区是否已决定最佳做法?是否使用可选项并处理展开,隐式解包的选项并处理战略位置的非零检查,非选项并将init()添加到每个控制器?或者是否有一个更好的解决方案我还没有遇到过?
非常感谢任何想法/建议。
答案 0 :(得分:0)
你使用一个隐式解包的可选项是好的,只是因为你使用隐式解包的选项,没有什么可以阻止你在使用之前检查可选项是否为nil。
如果变量为nil,请在函数顶部设置一个guard语句,以提前退出。