在Swift中可以吗?如果不是,那么是否有解决方法?
当前回答
要在swift中定义可选协议,你应该在协议声明和协议中的属性/方法声明之前使用@objc关键字。 下面是协议的可选属性示例。
@objc protocol Protocol {
@objc optional var name:String?
}
//现在,如果尝试在代码中实现该协议,将不会强制在类中包含该函数。
class MyClass: Protocol {
// No error
}
另一种方法是使用协议扩展,我们也可以给出该协议的默认实现。所以协议的功能是可选的。
其他回答
带有协议继承的纯Swift方法:
//Required methods
protocol MyProtocol {
func foo()
}
//Optional methods
protocol MyExtendedProtocol: MyProtocol {
func bar()
}
class MyClass {
var delegate: MyProtocol
func myMethod() {
(delegate as? MyExtendedProtocol).bar()
}
}
这里的其他答案涉及将协议标记为“@objc”,在使用swift特定类型时不起作用。
struct Info {
var height: Int
var weight: Int
}
@objc protocol Health {
func isInfoHealthy(info: Info) -> Bool
}
//Error "Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C"
为了声明能在swift中很好地工作的可选协议,将函数声明为变量而不是func。
protocol Health {
var isInfoHealthy: (Info) -> (Bool)? { get set }
}
然后实现如下协议
class Human: Health {
var isInfoHealthy: (Info) -> (Bool)? = { info in
if info.weight < 200 && info.height > 72 {
return true
}
return false
}
//Or leave out the implementation and declare it as:
//var isInfoHealthy: (Info) -> (Bool)?
}
然后可以使用“?”来检查函数是否已经实现
func returnEntity() -> Health {
return Human()
}
var anEntity: Health = returnEntity()
var isHealthy = anEntity.isInfoHealthy(Info(height: 75, weight: 150))?
//"isHealthy" is true
在协议中定义函数并为该协议创建扩展,然后为您想要作为可选使用的函数创建空实现。
有两种方法可以在swift协议中创建可选方法。
1 -第一个选项是使用@objc属性标记你的协议。虽然这意味着它只能被类采用,但它确实意味着你可以像这样将单个方法标记为可选的:
@objc protocol MyProtocol {
@objc optional func optionalMethod()
}
2 -更快的方式:这个选择更好。编写什么都不做的可选方法的默认实现,如下所示。
protocol MyProtocol {
func optionalMethod()
func notOptionalMethod()
}
extension MyProtocol {
func optionalMethod() {
//this is a empty implementation to allow this method to be optional
}
}
Swift有一个叫做扩展的特性,它允许我们为那些我们想要成为可选的方法提供一个默认实现。
这里有一个非常简单的例子,只适用于swift类,而不适用于结构或枚举。 注意,协议方法是可选的,有两个级别的可选链接。 同样,采用协议的类在声明中需要@objc属性。
@objc protocol CollectionOfDataDelegate{
optional func indexDidChange(index: Int)
}
@objc class RootView: CollectionOfDataDelegate{
var data = CollectionOfData()
init(){
data.delegate = self
data.indexIsNow()
}
func indexDidChange(index: Int) {
println("The index is currently: \(index)")
}
}
class CollectionOfData{
var index : Int?
weak var delegate : CollectionOfDataDelegate?
func indexIsNow(){
index = 23
delegate?.indexDidChange?(index!)
}
}
推荐文章
- 如何删除默认的导航栏空间在SwiftUI导航视图
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- 如何舍入一个双到最近的Int在迅速?
- 扁平化数组的数组在Swift
- Swift:声明一个空字典
- 在成功提交我的应用程序后,“太多符号文件”
- 从数组中随机选择一个元素
- 首先添加一个UIView,甚至是导航栏
- 我如何改变UIButton标题颜色?
- 在Swift中如何调用GCD主线程上的参数方法?
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- CFNetwork SSLHandshake iOS 9失败
- swift语言中的结构与类