一、應用場景:
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有什麼控件,
而且兩個類的耦合性增強,一旦其中的一個類不存在或者這個控件屬性不存在,程序就運行不了。
所以運用代理的方法可以實現沒了你,照樣運行,誰也不依賴誰。