我正在尝试将NSManagedObjectContext
从一个视图控制器传递到我的prepareForSegue
方法中的下一个视图控制器,但是我无法在destinationViewController
中访问我为其创建的属性}:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "segueToSettings", "pickLiftSegue":
if let nav = segue.destinationViewController as? UINavigationController {
let vc = nav.topViewController as! Dismissable
vc.dismissalDelegate = self
let context = viewModel.model.context
vc.moc = context // <-- Value of type Dismissable has no member `moc`
}
case "segueToLog":
let destinationVC = segue.destinationViewController as? Dismissable
destinationVC?.dismissalDelegate = self
default:
break
}
}
}
这是destinationViewController
的相关部分:
class SettingsViewController: UITableViewController, Dismissable, DismissalDelegateProtocol {
@IBOutlet weak var forumlasTitle: UILabel!
@IBOutlet weak var liftsTitle: UILabel!
@IBOutlet weak var weightUnitControl: UISegmentedControl!
@IBOutlet weak var roundNumbersSwitch: UISwitch!
@IBOutlet weak var currentFormulaSelection: UITableViewCell!
@IBOutlet weak var currentLiftsSelection: UITableViewCell!
var dismissalDelegate: DismissalDelegateProtocol?
var moc: NSManagedObjectContext? = nil // <-- There it is right there
}
我在vc.moc
中prepareForSegue
收到了您在上面看到的错误,这明显说明符合Dismassable协议的视图控制器没有名为moc
的属性,这是真的:
protocol Dismissable: class {
weak var dismissalDelegate: DismissalDelegateProtocol? { get set }
}
但是我不应该在不将其作为协议的一部分的情况下访问视图控制器本身的属性吗?
我已经搜索了很长一段时间并梳理了Apple's Protocol documentation,但我还没有找到答案。我以为我对协议有了很好的处理,但似乎我仍然缺少一两个关键概念。
答案 0 :(得分:1)
问题是编译器只知道你告诉它的内容。你说:
let vc = nav.topViewController as! Dismissable
现在vc
是一个Dismissable,它是编译器知道的 all 。并且Dismissable没有moc
属性。因此,当您尝试讨论Dismissable的moc
属性时,编译器会阻止您进入。
但是一个SettingsViewController 确实具有moc
属性,正如你自己指出的那样。所以告诉编译器这个是一个SettingsViewController,如果是这样的话:
if let svc = vc as? SettingsViewController {
svc.moc = context
}
但想想更多。由于SettingsViewController 是一个Dismissable,,并且编译器知道这个,实际上是你需要的仅强制转换,因为现在你也可以访问不允许的财产。因此,您的代码可以完全重写:
if let nav = segue.destinationViewController as? UINavigationController {
if let vc = nav.topViewController as? SettingsViewController {
vc.dismissalDelegate = self // fine, because a SVC is a Dismissable
let context = viewModel.model.context
vc.moc = context // fine, because a SVC is a SVC :)
}
}
换句话说,以这种方式看待它:编译器知道SettingsViewController是一个Dismissable。但没有法律规定每个Dismissable都是一个SettingsViewController。你的原始代码有向后的关系,就是这样。