Swift中的代表示例

Nik*_*har 21 delegates design-patterns protocols delegation swift

我一直在努力学习如何使用协议进行委派.我理解了一切,但我想不到何时使用委托除了使用表视图和可能滚动视图.

一般来说,何时使用授权?

Ahm*_*d F 61

什么是代表团?

首先,您应该知道,委派模式不是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()
    }
}
Run Code Online (Sandbox Code Playgroud)

查看控制器:

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!!")
    }
}
Run Code Online (Sandbox Code Playgroud)


小建议:

作为使用委派的常见示例之一是在视图控制器之间传递数据.

  • 可能是我见过的最好的例子,非常有帮助 (2认同)

Swe*_*per 5

当您想要将某些信息或对象A的状态传递给另一个对象B时,使用委派.通常,对象B是创建对象A的对象.

我将列出一些使用委托的情况.

  1. 你是对的.表视图和滚动视图使用委托,因为他们想告诉任何感兴趣的人(通常是你的视图控制器)"有人选择了一行!" 或者"有人滚动滚动视图!".滚动视图和表视图不仅使用委托,UITextField而且UIDatePicker许多其他视图也使用委托!

  2. 视图控制器也有代理.例如,UIImagePickerController.原因与上面大致相同 - 因为UIImagePickerController想要告诉你"已经选择了图像!"这样的消息.另一个例子是UIPopoverControllerDelegate.这个代表告诉你"popover已经被解雇了!"

  3. 其他使用委托的类包括CLLocationManager.该代表告诉您"已检测到用户位置"或"未检测到用户位置"等情况.

  4. 当您的某个视图控制器想要将消息发送到其他视图控制器时,您可以在代码中使用委托.如果是设置视图控制器,它可能会发送"字体大小设置已更改!"等消息.关注字体大小设置更改的视图控制器将知道并更改标签或其他内容的字体大小.