为什么swift中的“事件监听器”的概念在动作和协议之间划分?

问题描述 投票:2回答:2

我的问题

作为一个正在学习迅速的新程序员。我想知道为什么事件监听器如何实现之间似乎存在任意分歧。

在一些教程中,指出您可以简单地在故事板和视图控制器之间拖动视图元素来创建动作(事件侦听器)。

@IBAction func clickButtonListener(_ sender: UIButton) {
    print("hello world")
}

但是在后面的教程中,我注意到某些类似事件监听器的功能也以协议的形式实现

class ViewController: UIViewController, UIScrollViewDelegate {
     func scrollViewDidScroll(...) {
         ...
     }
}

我的问题

  1. 为什么看似有两种实现事件监听器的方法?
  2. 动作只是包装协议方法(是否建立在其他方面之上)?
  3. 每个的好处和缺点是什么?
swift xcode swift4
2个回答
5
投票
  1. 第一个概念叫做Target-Action,它最初来自Nextstep。针对侦听器协议的优点是,您只需要在类中实现一个已经拥有的方法。对于Java中的事件侦听器,如果视图包含多个按钮,则需要始终使用单独的类或if-else-chains。 第二种设计模式叫做Delegation。它对于需要多个不同回调的UI元素很有帮助,其中回调方法不能与动作方法之类的刚性签名相对应,或者可能具有与动作方法相反的返回值。
  2. 没有定义动作方法的协议。这是不可能的,因为名称可以自由选择。在iOS中,每个匹配所需形状的方法(参见上面的Target-Action链接)都可以是一个动作方法。
  3. 您可以根据需要在单个Cocoa类中实现尽可能多的操作方法。动作方法很容易创建(比如在Java中实现Runnable),并且由于可以自由选择名称而非常灵活。 另一方面,代表具有更多功能并允许更精确的回调规范。

注意(与Java相比):您可以在Java中将事件侦听器实现为独立类或匿名(内联)类。这些事件监听器类中的每一个都可以包含一个相同类型的事件监听器,因此大多数情况下选择内联变量以避免产生不必要的大量类。匿名类的优点还在于它们可以访问周围类的属性。

但是,如果在操作中需要许多事件侦听器,则代码会变得越来越复杂,并且由于更高的缩进级别而变得越来越难以辨认,特别是如果事件侦听器是嵌套的。

相比之下,Cocoa中动作方法的嵌套深度是平坦的。使用更多操作方法,类会变得更长,但各个方法不会变得更复杂。


2
投票

协议就像合同。当类型符合协议时,编译器可以在不知道编译时该类型在运行时实际将是什么的情况下推断该类型的行为。例如,滚动视图在编译时“知道”可能有一个实例想要知道滚动视图何时滚动。所以它发送该实例此消息。

目标行动是完全不同的。使用目标操作模式,可以在对象之间创建连接。假设您在UI中有一个按钮,并将连接拖到视图控制器上。然后按钮具有目标,并且当发生某些特定事件(例如,内部触摸事件)时,该按钮向连接的元素发送动作。您甚至可以向按钮询问所有已连接的目标。

© www.soinside.com 2019 - 2024. All rights reserved.