在Swift中,如何像Objective-C定义可选接口?
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类型,我们是无法令它们所实现的接口中含有可选方法或者属性的。
在Swift中,如何像Objective-C定义可选接口?的更多相关文章
- 一览Swift中的常用关键字
要学习Swift这门语言,就必须先了解Swift的关键字及对应的解释.这里就列一下在Swift中常用到的关键字. 关键字是类似于标识符的保留字符序列,除非用重音符号(`)将其括起来,否则不能用作标识符 ...
- Swift 中的基础语法(二)
1.Swift 中的函数 /// 函数的定义 /// /// - Parameters: /// - x: 形参 /// - y: 形参 /// - Returns: 返回值 func sum(x: ...
- Swift 中的协议
Swift 中的协议协议是为方法.属性等定义一套规范,没有具体的实现,类似于Java中的抽象接口,它只是描述了方法或属性的骨架,而不是实现.方法和属性实现还需要通过定义类,函数和枚举完成. 协议定义 ...
- [翻译]理解Swift中的Optional
原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...
- Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法
由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...
- 26.怎样在Swift中定义宏?
Swift 中没有宏定义,苹果建议使用let 或者 get 属性来替代宏定义值.虽然没有#define,但我们仍然可以使用 #if 并配合编译的配置来完成条件编译.下面会列出Swift项目开发中的一些 ...
- Swift中使用typealias定义一个闭包closure
在OC中我们定义一个Blocks是这样定义的: typedef void (^ZWProgressHUDCompletionBlock)(); 在Swift中定义一个闭包是这种: typealias ...
- Objective的宏到swift中该怎么办?
ReadMehtml, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scroll { ...
- swift中类似宏定义
建一个类 如,在Contans.swift中 import UIKit let kMAIN_SIZE = UIScreen.mainScreen().bounds 在其他地方直接用 比如在 MyTab ...
随机推荐
- [bzoj1005][HNOI2008][明明的烦恼] (高精度+prufer定理)
Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N ...
- String类的获取功能
/* * String类的获取功能: * int length():获取字符串的长度,其实也就是字符个数 * char charAt(int index):获取指定索引处的字符 * int index ...
- HUST 1214 Cubic-free numbers II
Cubic-free numbers II Time Limit: 10000ms Memory Limit: 131072KB This problem will be judged on HUST ...
- A^B Mod C
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = 3. Input 3个正整 ...
- android在listview中放入从sdcard读取的bitmap
重写viewbinder public class viewbinder_bookmark implements SimpleAdapter.ViewBinder{ @Override public ...
- CentOS设置程序开机启动程序/服务的方法(转)
注意:CentOS 6下基本没什么问题,CentOS 7估计不一定能行. 在CentOS系统下,主要有两种方法设置自己安装的程序开机启动. 1.把启动程序的命令添加到/etc/rc.d/rc.loca ...
- Android: MediaRecorder start failed
在某些机型上,MediaRecorder在调用start方法时,会出现start failed的错误,有一种可能是setVideoFrameRate导致的.要解决这个问题,只需要注释掉这条语句就可以了 ...
- 条款50: 提高对C++的认识
class Base { public: virtual void f(int x); }; class Derived: public Base { public: virtual void f(d ...
- Python FAQ1:传值,还是传引用?
在C/C++中,传值和传引用是函数参数传递的两种方式.由于思维定式,从C/C++转过来的Python初学者也经常会感到疑惑:在Python中,函数参数传递是传值,还是传引用呢? 看下面两段代码: de ...
- Java大数练习第二弹
hdu1250 水题 题目链接:pid=1250">http://acm.hdu.edu.cn/showproblem.php?pid=1250 import java.util.*; ...