2017-03-03 74 views
1

我想传递一个NSManagedObjectContext从一个视图控制器到下一个在我prepareForSegue方法,但我不能访问在destinationViewController我已经为它创建的属性:为什么我无法访问符合协议的此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协议视图控制器不具有财产卡莱d moc这是真的:

protocol Dismissable: class { 
    weak var dismissalDelegate: DismissalDelegateProtocol? { get set } 
    } 

,但我不应该能够访问视图控制器本身的属性没有使它的协议的一部分?

我搜索了很长一段时间,并通过Apple's Protocol documentation梳理,但我还没有找到答案。我认为我对协议有很好的处理,但似乎我仍然缺少一个或两个关键概念。

+1

在你的协议中你有'dismissalDelegate',但你正在设置'moc',它是你视图控制器的一部分。可能你需要将视图控制器转换为'SettingsViewController'而不是'Dismissible' – GoodSp33d

回答

1

问题是编译器只知道你说的是什么。你说:

let vc = nav.topViewController as! Dismissable 

现在vc是Dismissable,这是所有编译器知道。而且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。你原来的代码有向后的关系,就这些。

+0

并注意我使用'if let ... as?'。总是一个好主意,因为'as!'会使你崩溃。不是必需的,但是一个好习惯。 – matt

+0

感谢您的周到回答和奖金提示,@matt。 – Jim

相关问题