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


当前回答

让我们先来了解一下它们的区别

第一个例子-如果你写UITableViewDataSource,那么你需要强制写两个方法-这是默认协议的快速方式

第二个例子-如果你写UITableViewDelegate,并意识到它不会显示红色错误,请添加所有的委托方法。使用哪种方法取决于你自己。我们可以调用作为可选方法!

让我们通过一个例子来理解

第一种Swift方式默认协议方法

class ContactModel{
    var firstname: String?
    var lastname: String?
}

protocol ContactDataSource: AnyObject{
    func contactConfiguration(contact: ContactModel)
}

class ViewController: ContactDataSource{
    func contactConfiguration(contact: ContactModel) {
        print(contact)
    }
}

第二种方法——可选协议

@objc
class UserModel: NSObject{
    var firstname: String = ""
}

@objc protocol UserDataSource{
    func contactConfiguration(user: UserModel)
   @objc optional func userInfo(user: UserModel)
}

class ViewController: UserDataSource{
    func contactConfiguration(user: UserModel) {
        print(user)
    }
}

注意:如果你能在可选协议中看到,我还没有写userInfo方法,所以这取决于你。这意味着With和不向类添加方法 它工作得很好。-在协议中作为可选方法调用 类声明类和协议 @objc属性,它只与类而不是struct工作!

第三种方法-使用扩展的可选协议

注意:你可以选择Struct或Class

class UserModel{
    var firstname: String = ""
}

OR

struct UserModel{
    var firstname: String = ""
}

AND

protocol UserDataSource{
    func contactConfiguration(user: UserModel)
}

extension UserDataSource{
    func userInfo(user: UserModel){}
}

class myview: UserDataSource{
    func contactConfiguration(user: UserModel) {
        print(user)
    }
}

其他回答

与最初的问题有点偏离主题,但它建立在安托万的想法上,我想它可能会帮助到一些人。

您还可以为具有协议扩展的结构设置可选的计算属性。

您可以将协议上的属性设置为可选的

protocol SomeProtocol {
    var required: String { get }
    var optional: String? { get }
}

在协议扩展中实现虚拟计算属性

extension SomeProtocol {
    var optional: String? { return nil }
}

现在你可以使用实现或不实现可选属性的结构体

struct ConformsWithoutOptional {
    let required: String
}

struct ConformsWithOptional {
    let required: String
    let optional: String?
}

我还在我的博客上写了如何在Swift协议中执行可选属性,我会不断更新,以防Swift 2发布时情况发生变化。

下面是一个使用委托模式的具体示例。

设置您的协议:

@objc protocol MyProtocol:class
{
    func requiredMethod()
    optional func optionalMethod()
}

class MyClass: NSObject
{
    weak var delegate:MyProtocol?

    func callDelegate()
    {
        delegate?.requiredMethod()
        delegate?.optionalMethod?()
    }
}

将委托设置为类并实现协议。请注意,不需要实现可选方法。

class AnotherClass: NSObject, MyProtocol
{
    init()
    {
        super.init()

        let myInstance = MyClass()
        myInstance.delegate = self
    }

    func requiredMethod()
    {
    }
}

重要的一点是,可选方法是可选的,在调用时需要“?”。提到第二个问号。

delegate?.optionalMethod?()

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

 }

让我们先来了解一下它们的区别

第一个例子-如果你写UITableViewDataSource,那么你需要强制写两个方法-这是默认协议的快速方式

第二个例子-如果你写UITableViewDelegate,并意识到它不会显示红色错误,请添加所有的委托方法。使用哪种方法取决于你自己。我们可以调用作为可选方法!

让我们通过一个例子来理解

第一种Swift方式默认协议方法

class ContactModel{
    var firstname: String?
    var lastname: String?
}

protocol ContactDataSource: AnyObject{
    func contactConfiguration(contact: ContactModel)
}

class ViewController: ContactDataSource{
    func contactConfiguration(contact: ContactModel) {
        print(contact)
    }
}

第二种方法——可选协议

@objc
class UserModel: NSObject{
    var firstname: String = ""
}

@objc protocol UserDataSource{
    func contactConfiguration(user: UserModel)
   @objc optional func userInfo(user: UserModel)
}

class ViewController: UserDataSource{
    func contactConfiguration(user: UserModel) {
        print(user)
    }
}

注意:如果你能在可选协议中看到,我还没有写userInfo方法,所以这取决于你。这意味着With和不向类添加方法 它工作得很好。-在协议中作为可选方法调用 类声明类和协议 @objc属性,它只与类而不是struct工作!

第三种方法-使用扩展的可选协议

注意:你可以选择Struct或Class

class UserModel{
    var firstname: String = ""
}

OR

struct UserModel{
    var firstname: String = ""
}

AND

protocol UserDataSource{
    func contactConfiguration(user: UserModel)
}

extension UserDataSource{
    func userInfo(user: UserModel){}
}

class myview: UserDataSource{
    func contactConfiguration(user: UserModel) {
        print(user)
    }
}

在协议中定义函数并为该协议创建扩展,然后为您想要作为可选使用的函数创建空实现。