符合协议的类作为Swift中的函数参数

时间:2014-06-05 03:58:45

标签: swift

在Objective-C中,可以将符合协议的类指定为方法参数。例如,我的方法只允许符合UIViewController的{​​{1}}:

UITableViewDataSource

我无法在Swift中找到一种方法(也许它还不可能)。您可以使用- (void)foo:(UIViewController<UITableViewDataSource> *)vc; 指定多个协议,但是如何要求该对象也属于特定类?

8 个答案:

答案 0 :(得分:119)

您可以将foo定义为通用函数,并使用类型约束来同时要求类和协议。

Swift 4

func foo<T: UIViewController & UITableViewDataSource>(vc: T) {
    .....
}

Swift 3 (也适用于Swift 4)

func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { 
    ....
}

Swift 2

func foo<T: UIViewController where T: UITableViewDataSource>(vc: T) {
    // access UIViewController property
    let view = vc.view
    // call UITableViewDataSource method
    let sections = vc.numberOfSectionsInTableView?(tableView)
}

答案 1 :(得分:24)

在Swift 4中,您可以使用新的&amp;签名:

let vc: UIViewController & UITableViewDataSource

答案 2 :(得分:16)

Swift书籍文档建议您使用带有where子句的类型约束:

func someFunction<C1: SomeClass where C1:SomeProtocol>(inParam: C1) {}

这保证“inParam”的类型为“SomeClass”,条件是它也遵守“SomeProtocol”。您甚至可以指定由逗号分隔的多个where子句:

func itemsMatch<C1: SomeProtocol, C2: SomeProtocol where C1.ItemType == C2.ItemType,    C1.ItemType: SomeOtherProtocol>(foo: C1, bar: C2) -> Bool { return true }

答案 3 :(得分:4)

使用Swift 3,您可以执行以下操作:

func foo(_ dataSource: UITableViewDataSource) {
    self.tableView.dataSource = dataSource
}

func foo(_ delegateAndDataSource: UITableViewDelegate & UITableViewDataSource) { 
    //Whatever
}

答案 4 :(得分:3)

快捷键5:

func foo(vc: UIViewController & UITableViewDataSource) {
    ...
}

基本上是Jeroen的答案。

答案 5 :(得分:0)

2015年9月的注释:这是斯威夫特早期的观察。

似乎不可能。 Apple也对他们的一些API有这种烦恼。以下是iOS 8中新引入的一个示例(从测试版5开始):

UIInputViewController&#39; textDocumentProxy财产:

在Objective-C中定义如下:

@property(nonatomic, readonly) NSObject<UITextDocumentProxy> *textDocumentProxy;

并在Swift中:

var textDocumentProxy: NSObject! { get }

链接到Apple&#39;文档: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy

答案 6 :(得分:0)

这种方式怎么样?:

<div style="display:flex;align-items:center;justify-content:center;" id="content">
    <div>
        <h1>I'd love to be centre aligned correctly.</h1>
    </div>
</div>

答案 7 :(得分:0)

Swift 5 更新:

func yourFun<V: YourClass>(controller: V) where V: YourProtocol