在Swift中可以吗?如果不是,那么是否有解决方法?


当前回答

由于有一些关于如何使用可选修饰符和@objc属性来定义可选需求协议的答案,我将给出一个如何使用协议扩展定义可选协议的示例。

下面的代码是Swift 3.*。

/// Protocol has empty default implementation of the following methods making them optional to implement:
/// `cancel()`
protocol Cancelable {

    /// default implementation is empty.
    func cancel()
}

extension Cancelable {

    func cancel() {}
}

class Plane: Cancelable {
  //Since cancel() have default implementation, that is optional to class Plane
}

let plane = Plane()
plane.cancel()
// Print out *United Airlines can't cancelable*

请注意,Objective-C代码不能调用协议扩展方法,更糟糕的是Swift团队不会修复它。https://bugs.swift.org/browse/SR-492

其他回答

这里的其他答案涉及将协议标记为“@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 3.0中

@objc protocol CounterDataSource {
    @objc optional func increment(forCount count: Int) -> Int
    @objc optional var fixedIncrement: Int { get }
}

这会节省你的时间。

带有协议继承的纯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 3.*。

/// Protocol has empty default implementation of the following methods making them optional to implement:
/// `cancel()`
protocol Cancelable {

    /// default implementation is empty.
    func cancel()
}

extension Cancelable {

    func cancel() {}
}

class Plane: Cancelable {
  //Since cancel() have default implementation, that is optional to class Plane
}

let plane = Plane()
plane.cancel()
// Print out *United Airlines can't cancelable*

请注意,Objective-C代码不能调用协议扩展方法,更糟糕的是Swift团队不会修复它。https://bugs.swift.org/browse/SR-492

这里有一个非常简单的例子,只适用于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!)
    }

 }