我何时以及为何在Swift中使用协议?

时间:2018-11-18 14:13:36

标签: swift protocols swift-protocols customstringconvertible

所以我遇到了协议的主题,我在互联网上搜索了很多答案,但是找不到一个解决问题的方法。

因此,我知道协议是方法,属性等的“蓝图”,并且可以在类或结构中实现,并且需要符合其要求等,但是为什么要使用一个呢? / p>

我的意思是,您也可以在结构本身内部创建一个函数。编写协议似乎有点麻烦,然后要实现该协议,您这次必须使用更多代码再次编写所有需求。

有人会使用某种协议吗?是出于代码安全或其他原因?

例如:

您很快就会拥有CustomStringConvertible协议,该协议具有必需的计算属性,以控制如何将自定义类型表示为可打印的String值,但是您也可以在类内部创建一个函数来解决此问题。您甚至可以在不实现此协议的情况下拥有与该协议相同的计算属性。

因此,如果有人可以阐明这个问题,那就太好了。

提前谢谢!

3 个答案:

答案 0 :(得分:2)

  

但是为什么一个人会用一个?

Protocols迅速类似于其他一些语言中的Abstractions

在回答您的问题之前,我们必须先弄清楚所有事情,Protocols声明可能多种多样,但考虑到您已经读过很多,

也很高兴提到这个答案here

现在让我们进入这里的实际用例。

请考虑您有此协议。

protocol Printable {
var name: String { get }
}

现在,我们需要某种类型的structsclasses进行确认,或多个

这就是它最大的优点之一。

考虑到您必须打印对象的name属性。

例如那些。

    struct Human {
    var name: String
}
struct Animal {
    var name: String
}

您只需输入不带Protocols

    func printOut(human: Human){
    human.name
   }

   func printOut(animal: Animal){
    animal.name    
   }

这是正确的,现在使用协议Printable观察下面的代码。

struct Human: Printable {
    var name: String
}
struct Animal: Printable {
    var name: String
}

 func printOut(object: Printable){
    print(object.name)
   }

仅需我们一个func,依此类推,就可以使用Protocols

结论

  

用于最小化不必要的代码块的协议。

     

它的名称代表对确认方施加的效果。

     

可以将协议作为参数类型注入。

您还可以阅读有关here的更多信息。

有关用例here的更多信息。

答案 1 :(得分:0)

快速协议是一种模式,允许您的类确认特定的规则集。

换句话说,协议是特定任务所需的方法和属性的蓝图。

您通过确认来实施协议。如果您的类错过了协议中定义的任何方法的实现,则swift编译器会告诉您。

作为一个例子,让我们考虑您要创建一个Car类。现在对汽车有特殊要求。就像它有轮子,行李箱等。每个需求可以定义为一个协议,然后由Car类实现。如果您的班级没有中继,您只需删除实现。

面向协议的编程是一种新的编程范例。这解决了面向对象编程引起的一些问题。喜欢多重继承。 Swift不允许多重继承,但可以确认多种协议。

在面向协议的编程中,从类中删除某些功能非常容易。您只是停止遵守它。与OOP相比,在POP中很容易做到这一点。

答案 2 :(得分:0)

该协议的概念非常简单:无非是一个承诺,即在该协议上使用的任何对象中都会存在特定的方法和/或属性。因此,我们将它们用于打字和打字安全。

想象一下创建一个自定义控件,例如操作表:

class CustomActionSheet: UIControl {

    func userTappedOnSomething() {
        // user tapped on something
    }

}

...并且您在一个视图控制器中实现了它。

class SomeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let actionSheet = CustomActionSheet()
    }

}

在用户点击按钮时不让操作表与视图控制器进行通信就没有什么用了。所以我们使用一个委托:

class CustomActionSheet: UIControl {

    weak var delegate: UIViewController?

    func userTappedOnSomething() {
        delegate?.userTookAction()
    }

}

class SomeViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let actionSheet = CustomActionSheet()
        actionSheet.delegate = self

    }

    func userTookAction() {
        // update the UI
    }

}

现在,当用户点击操作表中的按钮时,下面的视图控制器可以更新其UI。但这实际上不会编译。您将收到一个错误消息,UIViewController没有成员userTookAction。这是因为UIViewController类没有名为userTookAction的方法,只有视图控制器的此实例才有。所以我们使用一个协议:

protocol ActionSheetProtocol: AnyObject {
    func userTookAction()
}

此协议说,符合该协议的任何对象都必须包含此方法。因此,我们将操作表的委托更改为该协议类型,并使视图控制器符合该协议,因为它具有以下方法:

class CustomActionSheet: UIControl {

    weak var delegate: ActionSheetProtocol?

    func userTappedOnSomething() {
        delegate?.userTookAction()
    }

}

class SomeViewController: UIViewController, ActionSheetProtocol {

    override func viewDidLoad() {
        super.viewDidLoad()

        let actionSheet = CustomActionSheet()
        actionSheet.delegate = self

    }

    func userTookAction() {
        // update the UI
    }

}

这是Swift中协议使用的经典示例,一旦您了解了它,您将学习如何精通协议并以非常聪明的方式使用它们。但是,无论您如何使用它们,概念仍然存在:保证事物将存在。

注意::在此示例中,我将协议命名为ActionSheetProtocol,因为对于学习协议的人来说,这是最有意义的。但是,在Swift领域中,按照当今的实践,大多数程序员(包括Apple的员工)都将其命名为ActionSheetDelegate。这可能会使学习协议的人感到困惑,因此在此示例中,我试图使其尽可能清晰。我个人不喜欢命名协议代表,但是有很多我不喜欢的东西。

注释2:我还制作了AnyObject类型的协议,这是Swift的语法,用于使该协议成为类协议。并非所有协议都必须为AnyObject类型。