在Swift属性中需要协议和类

las*_*sej 17 swift ios8

在Objective-C中,您可以要求属性的类和其他协议实现:

@property (nonatomic) UIViewController<UISplitViewDelegate> *viewController;
Run Code Online (Sandbox Code Playgroud)

这在Swift中可能吗?从文档中看起来你只需要一个类或一个协议.

aka*_*kyy 16

实际上有两种方法可以在Swift中实现这一点:

  1. 使用空的"幻像"协议.创建一个空协议并使其UIViewController符合它.这是最"Swift"的方法,它是安全的并且是动态的(不需要在编译时指定一个类).

    protocol _UIViewControllerType {}
    extension UIViewController: _UIViewControllerType {}
    
    class MyClass {
        weak var viewController: protocol<UISplitViewControllerDelegate, _UIViewControllerType>?
    }
    
    Run Code Online (Sandbox Code Playgroud)

    你也可以typealias为这种类型声明一个(只是为了减少代码混乱).

    class MyClass {
        typealias ViewControllerType = protocol<UISplitViewControllerDelegate, _UIViewControllerType>
        weak var viewController: ViewControllerType?
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用通用约束.如fnc12Konstantin Koval所述.这是安全的,但不允许您在运行时"交换"视图控制器实例.

    class MyClass<T: UIViewController where T: UISplitViewControllerDelegate> {
        weak var viewController: T?
    }
    
    Run Code Online (Sandbox Code Playgroud)

我希望下一个Swift版本添加一种方法来指定两个约束而不使用"幻像协议"......

typealias ViewControllerType = UIViewController: UISplitViewControllerDelegate // wish
Run Code Online (Sandbox Code Playgroud)


Jer*_*ker 3

在 Swift 4 中,您可以通过以下方式执行此操作:

let viewController: UIViewController & UISplitViewDelegate
Run Code Online (Sandbox Code Playgroud)