可选接口

Objective-C 中的 protocol 里存在 @optional 关键字,被这个关键字修饰的方法并非必须要被实现。我们可以通过接口定义一系列方法,然后由实现接口的类选择性地实现其中几个方法。在 Cocoa API 中很多情况下接口方法都是可选的,这点和 Swift 中的 protocol 的所有方法都必须被实现这一特性完全不同。

那些如果没有实现则接口就无法正常工作的方法一般是必须的,而相对地像作为事件通知或者对非关键属性进行配置的方法一般都是可选的。最好的例子我想应该是 UITableViewDataSource 和 UITableViewDelegate。前者中有两个必要方法:

-tableView:numberOfRowsInSection:
-tableView:cellForRowAtIndexPath:

分别用来计算和准备 tableView 的高度以及提供每一个 cell 的样式,而其他的像是返回 section 个数或者询问 cell 是否能被编辑的方法都有默认的行为,都是可选方法;后者 (UITableViewDelegate) 中的所有方法都是详细的配置和事件回传,因此全部都是可选的。

原生的 Swift protocol 里没有可选项,所有定义的方法都是必须实现的。如果我们想要像 Objective-C 里那样定义可选的接口方法,就需要将接口本身定义为 Objective-C 的,也即在 protocol 定义之前加上 @objc。另外和 Objective-C 中的 @optional 不同,我们使用没有 @ 符号的关键字 optional 来定义可选方法:

@objc protocol OptionalProtocol {
    optional func optionalMethod()
}

另外,对于所有的声明,它们的前缀修饰是完全分开的。也就是说你不能像是在 Objective-C 里那样用一个 @optional 指定接下来的若干个方法都是可选的了,必须对每一个可选方法添加前缀,对于没有前缀的方法来说,它们是默认必须实现的:

@objc protocol OptionalProtocol {
    optional func optionalMethod()  // 可选
    func necessaryMethod()          // 必须
    optional func anotherOptionalMethod() // 可选
}

一个不可避免的限制是,使用 @objc 修饰的 protocol 就只能被 class 实现了,也就是说,对于 struct 和 enum 类型,我们是无法令它们所实现的接口中含有可选方法或者属性的。

最后修改时间为:2015 年 05 月 18 日 03 时 45 分 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论