一尘不染

Swift中的代表示例

swift

我一直在尝试学习委托协议的工作方式。我了解所有内容,但是除了使用表视图和可能的滚动视图时,我无法想到何时使用委派。

通常,什么时候使用委托?


阅读 309

收藏
2020-07-07

共1个答案

一尘不染

什么是委派?

首先,您应该知道委派模式不是iOS世界专用的:

在软件工程中,委托模式是面向对象编程中的一种设计模式,它允许对象组合实现与继承相同的代码重用。

但是在iOS世界中使用委托非常普遍,我假设您可以看到许多提供委托/数据源的类,这些类提供了为使用的实例提供属性或行为的能力。它是对象在CocoaTouch中如何相互交谈的主要机制之一。


备择方案:

但是,委派 不是 让对象在iOS中彼此交谈的唯一方法,您可能想知道:

备注 :如果您有兴趣比较它们,则可能需要查看以下文章:


何时使用委派?

因此,问题是:“那我为什么要使用委托而不是那些选项?”

我将尝试使其变得简单;当两个对象之间具有 一对一 关系时,我建议使用委托。这只是为了更清晰的 目标, 说话有点有关的 通知中心
是当使用代表团尝试是有意义的:

NotificationCenter 代表 一对多 关系;简单来说,它的工作方式是:在特定事件上 发布(通知) 通知,并
观察(获得通知) 此通知-可以 其他 任何
地方观察到;从逻辑上讲,这就是一对多关系的意思。它是观察者模式的表示。


如何申请授权?

为了简化起见,我将其作为步骤提及:

  1. 了解要求: 每个委托都有自己的 规则 ,在 委托协议中 列出,该 规则 是一组应符合此委托的方法签名。

  2. 符合委托: 通过标记,让您的班级成为委托。例如:class ViewController: UIViewController, UITableViewDelegate {}

  3. 连接委托对象: 标记你的类是委托是 足够的,你需要确保让您想要的对象由类确认,提供所需的工作,你的类。

  4. 实现需求: 最后,您的类 必须 实现委托协议中列出的所有必需方法。


例如

听起来有点令人困惑吗?那么一个真实的例子呢?

请考虑以下情形:

假设您正在构建与播放音频有关的应用程序。一些viewControllers应该具有 音频播放器
的视图。在最简单的情况下,我们假设它应该有一个播放/暂停按钮和另一个按钮,让我们以某种方式显示播放列表,而不管其外观如何。

到目前为止,音频播放器视图具有单独的UIView类和.xib文件。应该将其作为子视图添加到任何所需的viewController中。

现在,如何为每个viewController的两个按钮添加功能?您可能会想:“简单来说,我将IBAction在视图类中添加一个就可以了”,乍一看,听起来似乎还可以,但是经过一番思考之后,您将意识到,如果您是尝试处理在控制器层点击按钮的事件;为了清楚起见,如果在音频播放器视图中点击按钮时,每个viewController实现不同的功能怎么办?例如:在“A”viewController中点击播放列表将显示一个tableView,但在“ B” viewController中点击播放列表将显示一个选择器。

好吧,让我们对这个问题应用 委派

“#”注释代表“如何申请授权?”的步骤。 部分。

音频播放器视图:

// # 1: here is the protocol for creating the delegation
protocol AudioPlayerDelegate: class {
    func playPauseDidTap()
    func playlistDidTap()
}

class AudioPlayerView: UIView {
    //MARK:- IBOutlets
    @IBOutlet weak private var btnPlayPause: UIButton!
    @IBOutlet weak private var btnPlaylist: UIButton!

    // MARK:- Delegate
    weak var delegate: AudioPlayerDelegate?

    // IBActions
    @IBAction private func playPauseTapped(_ sender: AnyObject) {
        delegate?.playPauseDidTap()
    }

    @IBAction private func playlistTapped(_ sender: AnyObject) {
        delegate?.playlistDidTap()
    }
}

视图控制器:

class ViewController: UIViewController {
    var audioPlayer: AudioPlayerView?

    // MARK:- Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        audioPlayer = AudioPlayerView()
        // # 3: the "AudioPlayerView" instance delegate will implemented by my class "ViewController"
        audioPlayer?.delegate = self
    }
}

// # 2: "ViewController" will implement "AudioPlayerDelegate":
extension ViewController: AudioPlayerDelegate {
    // # 4: "ViewController" implements "AudioPlayerDelegate" requirments:
    func playPauseDidTap() {
        print("play/pause tapped!!")
    }

    func playlistDidTap() {
        // note that is should do a different behavior in each viewController...
        print("list tapped!!")
    }
}

小建议:

作为一个
使用代表团最典型的例子是数据传递回]视图控制器之间。

2020-07-07