我想定义一个符合UIViewController
类型P1
的变量。
问题:
代码:
protocol P1 {
func f1();
}
var v1 : P1 //But needs to be a UIViewController which conforms to `P1`
答案 0 :(得分:15)
在Swift 4中,您可以使用新的&签署一个符合协议和类的变量,语法如下:
let vc: UIViewController & P1
答案 1 :(得分:10)
截至Swift 4:
感谢SE-0156:
该提案保留现有的
&
语法,但允许其中一个元素为AnyObject
或类类型。上述Objective-C类型的等价物如下所示:AnyObject & Protocol1 & Protocol2 Base & Protocol
与Objective-C一样,第一行是符合
Protocol1
和Protocol2
的类的存在性,第二行是符合Base
的{{1}}子类的存在性。Protocol
。
..我们现在可以声明:
var v1 : UIViewController & P1 // UIViewController which conforms to `P1`
之前的Swift 4:
没有办法直接这样做。您必须将v1
声明为UIViewController
或P1
,然后使用强制转换(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