我不能在开关内沮丧吗? (斯威夫特 3)

Posted

技术标签:

【中文标题】我不能在开关内沮丧吗? (斯威夫特 3)【英文标题】:Can't I downcast inside a switch ? (Swift 3) 【发布时间】:2016-11-05 20:46:30 【问题描述】:

我在同一个 prepareForSegue 中有 2 个 segue,一个连接到 UIViewController 子类,另一个连接到 UICollectionViewController 子类。 我正在尝试使用具有多态性的开关/案例来设置我的destinationViewController,但是我在开关内所做的向下转换在它之外是不可见的,它一直将var视为最初声明的UIVC。我在这里做错了什么? 错误是“'UIViewController' 类型的值没有成员 'context'”

 let identifier: String!
 var destinationTest: UIViewController!

    switch identifier 
    case "Add Exercise":
            destinationTest = segue.destination as! AddExerciseViewController
    case "addExerciseInCollectionView":
            destinationTest = segue.destination as! AddExerciseCollectionVC
    default: 
         break
    

 destinationTest.context = self.context

【问题讨论】:

destinationTest 被声明为UIViewController,所以这就是变量的全部内容。它可能指向UIViewController 的其他子类,但您将无法使用UIViewController 变量访问任何特定于子类的属性/函数。仅供参考 - 这与使用 switch 无关。 对于您必须工作的代码,您的两个视图控制器类要么需要共享一个超类(或更好),要么实现一个引入context 属性的协议。然后,您可以使用该类/协议而不是 UIViewController 作为 destinationTest 的类型 好的,它们都继承自 UIViewController,但是,上下文属性是在 UIViewController 的第三个子类中声明的,它是同级子类。我现在明白了为什么即使在沮丧之后这两个控制器也看不到我的财产。我认为这是开关内部的范围问题,哈哈。非常感谢你们!! 【参考方案1】:

您的视图控制器需要符合具有context 的协议,否则只需考虑单独执行它们。

switch (segue.identifier, segue.destination) 
case ("Add Exercise", let controller as AddExerciseViewController:
    controller.context = self.context
case ("addExerciseInCollectionView", let controller as AddExerciseCollectionVC:
    controller.context = self.context
default: 
     break

【讨论】:

【参考方案2】:

正如 RMaddy 所说,您已将 destinationTest 声明为 UIViewController,因此即使您在开关内部分配特定的 UIViewController 子类,编译器只知道 destinationTestUIViewController,因此您无法通过此变量访问任何子类属性。

您要么需要您的两个视图控制器子类从一个公共超类继承,该超类定义了context 属性并将destinationTest 声明为该超类,或者使用提供context 属性的协议:

property HasContext 
    var context: Context  set get 


class AddExerciseViewController: UIViewController, HasContext 

    var context: Context

    ...


class AddExerciseCollectionVC: UIViewController, HasContext 

    var context: Context

    ...

那你可以说

let identifier: String!
var destinationTest: HasContext!

switch identifier 
    case "Add Exercise":
            destinationTest = segue.destination as! HasContext
    case "addExerciseInCollectionView":
            destinationTest = segue.destination as! HasContext
    default: 
         break
 

 destinationTest.context = self.context

【讨论】:

以上是关于我不能在开关内沮丧吗? (斯威夫特 3)的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将数字附加到我的变量?!在斯威夫特 3

斯威夫特:不能把一个数组为零

斯威夫特:这个错误:'private(set)'修饰符不能应用于只读属性是啥意思?

显示表格内的图像时出错!斯威夫特 3

解析和斯威夫特。获取 UITableView 中带有复选标记的单元格。 “不能调用参数。”

不能因为类不是多态而沮丧?