特定班级的快速协议

时间:2016-02-17 09:35:14

标签: swift protocols

我想定义一个符合UIViewController类型P1的变量。

问题:

  • 我应该修改协议还是v1类型?
  • 我该怎么做?

代码:

protocol P1 {

    func f1();
}


var v1 : P1 //But needs to be a UIViewController which conforms to `P1`

4 个答案:

答案 0 :(得分:15)

在Swift 4中,您可以使用新的&签署一个符合协议和类的变量,语法如下:

let vc: UIViewController & P1

答案 1 :(得分:10)

截至Swift 4:

感谢SE-0156

  

该提案保留现有的&语法,但允许其中一个元素为AnyObject或类类型。上述Objective-C类型的等价物如下所示:

AnyObject & Protocol1 & Protocol2
Base & Protocol
     

与Objective-C一样,第一行是符合Protocol1Protocol2的类的存在性,第二行是符合Base的{​​{1}}子类的存在性。 Protocol

..我们现在可以声明:

var v1 : UIViewController & P1 // UIViewController which conforms to `P1`

之前的Swift 4:

没有办法直接这样做。您必须将v1声明为UIViewControllerP1,然后使用强制转换(as)才能获得其他功能。

最近,你可以通过泛型获得你想要的东西。例如:

func testGeneric<T: UIViewController where T: P1>(input: T) {
    input.f1()
}

例如,如果你的情况是委托既是继承的控制器又是协议实现的委托,那么你可以沿着以下几行:

protocol Delegate: class { 
    func doDelegate()
}

class Controller { 
    func doController() {
        print("Controller")
    }
}

class ConcreteController: Controller, Delegate {
    func doDelegate() {
        print("Delegate")
    }
}

class View {
    private weak var controller: Controller? = nil
    private weak var delegate: Delegate? = nil

    func setDelegateController<T: Controller where T: Delegate>(delegateController: T?) {
        controller = delegateController
        delegate = delegateController
    }

    func test() {
        controller?.doController()
        delegate?.doDelegate()
    }
}

并测试一下:

let view = View()
let controller = ConcreteController()

view.setDelegateController(controller)

view.test()  // This will print:
             // Controller
             // Delegate

答案 2 :(得分:1)

您可以创建另一个空协议,将UIViewController约束到该协议,然后使用protocol<>指令将两个协议合并为一个类型:

protocol UIViewControllerType {} // empty
protocol P1 { ... }

// Make sure only UIViewController adopts UIViewControllerType
extension UIViewController: UIViewControllerType {}

extension UITableViewController: P1 {}

// This works:
var v1: protocol<UIViewControllerType, P1> = UITableViewController()

// This doesn't:
var v2: protocol<UIViewControllerType, P1> = UIViewController()

答案 3 :(得分:0)

这样:

protocol P1 {
    func f1()
    func getVC() -> UIViewController
}

class MyVC : UIViewController, P1 {

    func f1() {
        // do stuff
    }

    func getVC() -> UIViewController {
        return self
    }
}

var v1 : P1 = MyVC()

v1.getVC() // do UIViewController related things