如何在Objective-C中使用delegate

stackoverflow上關于Objective-C關注度比較高的問題系列
鏈接

如何在Objective-C中使用delegate

原文鏈接《How do I create delegates in Objective-C?》
本文Github鏈接,含代碼

關鍵詞

delegate
Objective-C
Swift

delegate就是一個對象A代表另一個對象B處理一些事情(實現(xiàn)某種功能)。這里的對象A為代理方,對象B為委托方。代理方所要處理的事情是委托方通過協(xié)議指定的。這里我們提到了協(xié)議,代理方和委托放三個概念。

  • 協(xié)議:用來指定代理雙方可以做什么和必須做什么。
  • 代理方:根據(jù)指定的協(xié)議,完成委托放需要實現(xiàn)的功能(需求)。
  • 委托方:根據(jù)指定的協(xié)議,指定代理方完成什么功能。

這里舉一個主機+顯示器的例子來闡述這個代理模式。

主機把圖像信息給顯示器,然后顯示器顯示畫面。我們按照上述三個部分來對號入座:

  • 協(xié)議:“顯示圖像協(xié)議”,顯示畫面這件事情。
  • 代理方:顯示器,根據(jù)“顯示圖像協(xié)議”,實現(xiàn)主機(委托方)需要顯示畫面的需求。
  • 委托方:主機,根據(jù)“顯示圖像協(xié)議”,指定顯示器(代理方)顯示畫面。

具體creat一個delegate可以分為以下六步:

  • step1:聲明一個協(xié)議并在協(xié)議中明確可以做什么和必須做什么;
  • step2:委托方添加一個屬性deleget,該屬性向外界說明我有一個代理職位(需要遵從step1中的協(xié)議),類比:主機上的視頻接口(VGA、HDMI);
  • step3:委托方在需要完成某種功能的(協(xié)議中已提前確定)時候,告訴代理幫我完成這個功能,類比:主機需要顯示畫面;
  • step4:代理方需要遵從step1中的協(xié)議;
  • step5:代理方需要成為委托方的代理,類比:顯示器工作VGA線連接到主機;
  • step6:代理方在接受到委托方需要完成某種功能的信息后,實現(xiàn)該功能,類比:顯示畫面

以上六步中前三步都是在委托方中完成,后三步都是在代理方完成。

代碼展示

協(xié)議:HostDelegate
委托方:Host
代理方:Monitor

step1:申明一個協(xié)議HostDelegate

在Host.h中

必須做:顯示畫面
可以做:播放聲音

@class Host;
@protocol  HostDelegate <NSObject>

@required   //@required表示必須要做的

- (void)host:(Host *) host willDisplayPicture:(NSString *)content;

@optional   //@optional表示可以做但不用必須做

- (void)host:(Host *) host willPlayAudio:(NSString *)content;

step2:添加delegate屬性

在Host.h中

@interface Host: UIView

@property (nonatomic, weak) id<HostDelegate> delegate;

@end

step3:在需要展示畫面的時候調(diào)用

在Host.m中

//這里我們假設點擊了playButton觸發(fā)顯示畫面
//先判斷host的代理是否實現(xiàn)了協(xié)議中的方法,若沒有實現(xiàn)該方法程序會crash。
//通過 - (BOOL)respondsToSelector:(SEL)aSelector 方法判斷

- (IBAction)playButtonClicked:(id)sender {
    if ([self.delegate respondsToSelector:@selector(host:willDisplayPicture:)]) {
        [self.delegate host:self willDisplayPicture:@"你要的畫面"];
    }
    
}

step4:代理方需要遵從step1中的協(xié)議

在Monitor.h中

#import "Host.h"

@interface Monitor : NSObject <HostDelegate>

@property (nonatomic, strong) Host *host;

@end

step5:代理方需要成為委托方的代理

在Monitor.m中

- (Host *) host {
    if (!_host) {
        _host = [[Host alloc] init];
        _host.delegate = self;          //Monitor成為host的代理
    }
    return _host;
}

step6:代理方在接受到委托方需要完成某種功能的信息后

在Monitor.m中

- (void)host:(Host *) host willDisplayPicture:(NSString *)content {
    NSLog(@"display content = %@", content);
}

- (void)host:(Host *) host willPlayAudio:(NSString *)content {
    NSLog(@"playAudio content = %@", content);
}

代碼展示Swift

step1:申明一個協(xié)議HostDelegate

在Host.swift中

必須做:顯示畫面
可以做:播放聲音

@objc protocol HostDelegate: NSObjectProtocol {
    
    func host(_ host: Host, willDisplayPicture content: String) -> Void
    
    @objc optional func host (_ host: Host, willPlayAudio content: String) -> Void
}

如果不需要添加optional的方法,則如下

protocol HostDelegate: NSObjectProtocol {
    
    func host(_ host: Host, willDisplayPicture content: String) -> Void
}

step2:添加delegate屬性

在Host.swift中

class Host: UIView {
    
    public weak var delegate:HostDelegate?   
}

step3:在需要展示畫面的時候調(diào)用

在Host.swift中

//這里我們假設點擊了playButton觸發(fā)顯示畫面
//先判斷host的代理是否實現(xiàn)了協(xié)議中的方法,若沒有實現(xiàn)該方法程序會crash。
//通過 func responds(to aSelector: Selector!) -> Bool 方法判斷

@IBAction func playButtonClicked(_ button:UIButton) {
    
    if (self.delegate != nil &&
        (self.delegate?.responds(to: #selector(HostDelegate.host(_:willDisplayPicture:))))!) {
        self.delegate?.host(self, willDisplayPicture: "你要的畫面")
    }
}

step4:代理方需要遵從step1中的協(xié)議

在Monitor.swift中


class Monitor: UIViewController, HostDelegate {
}

step5:代理方需要成為委托方的代理

在Monitor.swift中

lazy var host: Host = {
    let host = Host.init(frame: CGRect(x: 0, y: 200, width: kScreenWidth, height: 100))
    host.delegate = self        //Monitor成為host的代理
    return host
}()

step6:代理方在接受到委托方需要完成某種功能的信息后

在Monitor.swift中

func host(_ host: Host, willDisplayPicture content: String) {
    NSLog("display content = %@", content)
}

func host(_ host: Host, willPlayAudio content: String) {
    NSLog("playAudio content = %@", content)
}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容