自定義delegate模式

一、應用場景:
A對象監聽B對象的狀態
或者B對象的狀態改變,通知A對象


二、成爲代理
必須遵守協議:
例如:UIScrollViewDelegate:滾動協議
UIAlertViewDelegate:彈框協議
UITextFieldDelegate:文本協議
................

另外蘋果官方給出:雖然遵守的協議,但是不強求實現它裏面的方法,因爲有@optional


三、使用delegate代理步驟
1.先搞清楚誰是誰的代理(delegate)

2.定義代理協議,協議名稱的命名規範:控件類名+ Delegate

3.定義代理方法
Ø代理方法一般都定義爲@optional
Ø代理方法名都以控件名開頭
Ø代理方法至少有1個參數,將控件本身傳遞出去
Ø
4.設置代理(delegate)對象  (比如myView.delegate=xxxx;)
Ø代理對象遵守協議
Ø代理對象實現協議裏面該實現的方法
Ø
5.在恰當的時刻調用代理對象(delegate)的代理方法,通知代理髮生了什麼事情

(在調用之前判斷代理是否實現了該代理方法)



四、自定義delegate模式
一個常見的用法(ViewControler監聽自定義的view-->AppView(即AppView.xib對應的類))
第一步:
聲明一個屬性
AppView.h文件中聲明協議和代理屬性

@class AppData,AppView;

@protocol AppViewDelegate <NSObject>

@optional
- (void)appViewClickDownLoad:(AppView *)appView;

@end
@interface AppView : UIView

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


這裏必須提出的是:協議的命名規範,你會經常看到很多協議都是以本身控件的名稱命名的,例如UIScrollViewDelegate協議就是以ScorllView命名的,所以我們這裏也遵守以下,哪個view聲明的我就以哪個類命名。

@property (weak, nonatomic) id<AppViewDelegate> delegate;
聲明一個遵守AppViewDelegate 協議的屬性提供外部調用。

- (void)appViewClickDownLoad:(AppView *)appView;
聲明一個一協議開頭的方法。這裏的方法含義是:我點擊xib的下載按鈕控件,然後通過代理,在ViewControler實現控件的增加刪除等改變


方法上由一個關鍵字@optional,表示可以成爲代理,但是不強求實現這個方法。


AppView.h文件中實現方法



- (IBAction)download:(UIButton *)button {

    // 告知代理
    if ([self.delegate respondsToSelector:@selector(appViewClickDownLoad:)]) {
        [self.delegate appViewClickDownLoad:self];
    }
 
}

注意:
紅色那個方法:判斷一下有沒有這個方法,如果有這個方法,我就調用 [self.delegate appViewClickDownLoad:self];
如果不加判斷,又沒有這個方法,直接調用,就會出現錯誤。




OK!協議和方法都弄好了。接下來就讓ViewController成爲代理
ViewController.m文件中
1、遵守協議

2、創建AppView對象,拿到裏面的代理屬性delagate。並賦值給當前的view。
3、實現協議裏面的方法

從代碼中,我們實現這個方法無非就是想在ViewControler這個類中增加一個控件而已([self.view addSubview:tipMessage];),

但是這個控件的觸發確實xib裏面按鈕。雖然實現方法很多:例如在AppView類中提供一個控件屬性,

然後在ViewControler賦值,但是這樣做不僅暴露AppView有什麼控件,

而且兩個類的耦合性增強,一旦其中的一個類不存在或者這個控件屬性不存在,程序就運行不了。

所以運用代理的方法可以實現沒了你,照樣運行,誰也不依賴誰。





































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章