首页 文章

引用符合协议的类

提问于
浏览
3

假设我有一个看起来像这样的协议:

protocol Foo {
    var bar: Bool { get set }
}

现在我的视图控制器符合Foo协议;

class FooViewController: UIViewController, Foo {
    ...
}

在另一个 class ,我想做这样的事情:

class FooClass {

    var viewController: UIViewController? // this should conform to Foo protocol

    func setViewController(viewController: UIViewController) {
        if let fooVC = viewController as? Foo {
            // viewController implements Foo protocol
            self.viewController = fooVC
        } else {
            print("ViewController does not conform to Foo protocol")
        }
    }
}

在Objective-C中我会有一个类似的引用: UIViewController<Foo> *vc 表示vc是符合Foo协议的类UIViewController的对象 . 有Swift等价物吗?

EDIT: 我猜是not possible :(

4 回答

  • 1

    Warning :这个解决方案可能会变得非常痛苦 .

    作为一种解决方法,您可以使用协议组合并最终使用扩展 .

    在您的示例中,您可能只对 UIResponder 符合的 UIResponder 协议方法感兴趣 .

    typealias FooController = protocol<UIResponder, Foo>
    
    class FooClass {
    
      var viewController: FooController?
    
      func setViewController(viewController: FooController) {
        // viewController implements UIResponder and Foo protocols
      }
    }
    

    UIViewController 具有不符合任何协议的属性和方法 . 在这种情况下,您可以制作包含所需方法的协议并扩展 UIViewController .

    protocol ViewEvent {
      func viewWillAppear(animated: Bool)
      func viewDidAppear(animated: Bool)
      func viewWillDisappear(animated: Bool)
      func viewDidDisappear(animated: Bool)
    }
    
    extension UIViewController: ViewEvent {}
    
    typealias FooController = protocol<UIResponder, ViewEvent, Foo>
    
  • 2

    这是解决方案:

    typealias FooController = UIViewController & Foo
    
    class FooClass {
    
        var viewController: FooController?
    
        func setViewController(viewController: FooController) {
            self.viewController = viewController
        }
    }
    
  • 0

    我明白你的意思了 .

    我认为您不能声明给定类类型的变量 and 符合协议 .

    但是,如果您只需要检查 viewController 是否符合 Foo 协议(并且您实际上不需要使用 Foo 中声明的bar属性),那么您可以执行此操作 .

    func setViewController(viewController: UIViewController) {
        if viewController is Foo {
            self.viewController = viewController
        } else {
            print("ViewController does not conform to Foo protocol")
        }
    }
    
  • 2

    您可以定义为 viewController:Foo?

    根据我们的评论,你应该使用 if let fooVC = viewController as? FooViewController . 如果你是可选的将viewController绑定到Foo,那么将它分配给UIViewController实例是行不通的 .

相关问题