ios中關於delegate(委託)的使用心得
阿新 • • 發佈:2019-01-06
委託是Cocoa中最簡單、最靈活的模式之一。委託是指給一個物件提供機會對另一個物件中的變化做出反應或者影響另一個物件的行為。其基本思想是:兩個物件協同解決問題。一個物件非常普通,並且打算在廣泛的情形中重用。它儲存指向另一個物件(即它的委託)的引用,並在關鍵時刻給委託發訊息。訊息可能只是通知委託發生了某件事情,給委託提供機會執行額外的處理,或者訊息可能要求委託提供一些關鍵的資訊以控制所發生的事情。
4 天前 上傳下載附件 (18 KB) 委託方法通常包括3種動詞:should、will、did。
should表示一個動作發生前,通常帶有返回值,可以在動作發生之前改變物件狀態。
will在動作發生前,委託可以對動作做出響應,但不帶有返回值。
did在動作發生後做出的響應。
從方法的定義我們不難看出委託模式能夠起到兩方面的作用:
第一:委託協助物件主體完成某項操作,將需要定製化的操作通過委託物件來自定義實現,達到和子類化物件主體同樣的作用。
第二:事件監聽,委託物件監聽物件主體的某些重要事件,對事件做出具體響應或廣播事件交給需要作出響應的物件。
個人理解採用委託模式的好處在於:
1、避免子類化帶來的過多的子類以及子類與父類的耦合
2、通過委託傳遞訊息機制實現分層解耦
委託模式的實現思路:
1、通常是在物件主體包含一個委託物件的弱引用:
@interface A : NSObject
{
IBOutlet id delegate;
} -(id) delegate;
-(void) setDelegate:(id)obj;
2、委託物件的實現有兩種方式:正式協議和非正式協議,物件主體在協議中定義委託方法,委託物件可以選擇實現其中某些委託方法,因此如果通過正式協議定義委託方法需要使用@option。
@protocol NSSearchDelegate
@option
-(void)didSearchFinish:(*NSNotification) aNotification;
@end
3、連線物件主體和委託,無非就是通過setDelegate:(id)obj來實現。
4、觸發委託方法。
4 天前 上傳下載附件 (18 KB) 委託方法通常包括3種動詞:should、will、did。
should表示一個動作發生前,通常帶有返回值,可以在動作發生之前改變物件狀態。
will在動作發生前,委託可以對動作做出響應,但不帶有返回值。
did在動作發生後做出的響應。
從方法的定義我們不難看出委託模式能夠起到兩方面的作用:
第一:委託協助物件主體完成某項操作,將需要定製化的操作通過委託物件來自定義實現,達到和子類化物件主體同樣的作用。
第二:事件監聽,委託物件監聽物件主體的某些重要事件,對事件做出具體響應或廣播事件交給需要作出響應的物件。
個人理解採用委託模式的好處在於:
1、避免子類化帶來的過多的子類以及子類與父類的耦合
2、通過委託傳遞訊息機制實現分層解耦
委託模式的實現思路:
1、通常是在物件主體包含一個委託物件的弱引用:
{
IBOutlet id delegate;
} -(id) delegate;
-(void) setDelegate:(id)obj;
2、委託物件的實現有兩種方式:正式協議和非正式協議,物件主體在協議中定義委託方法,委託物件可以選擇實現其中某些委託方法,因此如果通過正式協議定義委託方法需要使用@option。
@protocol NSSearchDelegate
@option
-(void)didSearchFinish:(*NSNotification) aNotification;
@end
3、連線物件主體和委託,無非就是通過setDelegate:(id)obj來實現。
4、觸發委託方法。
昨天做了一個demo,用到了簡單代理。
delegate是ios程式設計的一種設計模式。我們可以用這個設計模式來讓單繼承的objective-c類表現出它父類之外類的特徵。昨天這個代理實現如下:
類GifView是繼承自UIView的,它載入在RootViewController上來通過一個Timer播放動畫。同時,RootViewController需要知道Timer的每次執行。
程式碼如下。
首先,定義GifView,在其標頭檔案中定義代理EveryFrameDelegate,同時宣告方法- (void)DoSomethingEveryFrame;
#import <UIKit/UIKit.h> @protocolEveryFrameDelegate <NSObject> - (void)DoSomethingEveryFrame; @end @interface GifView : UIView { NSTimer *timer; id <EveryFrameDelegate> delegate; NSInteger currentIndex; } @property (nonatomic, retain) id <EveryFrameDelegate> delegate; @end
然後,只要在GifView.m中讓Timer在每次執行的時候呼叫delegate來執行DoSomethingEveryFrame,程式碼如下
- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(play) userInfo:nil repeats:YES]; [timer fire]; } return self; } -(void)play { [delegate DoSomethingEveryFrame]; }
GifView上的工作就完成了。
下面是RootViewController中的程式碼,RootViewController只要在定義GifView的時候指定其代理為自身,就可以知道Timer的每次執行:
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CGRect rect = CGRectMake(0, 0, 200, 200); GifView *tmp = [[GifView alloc] initWithFrame:rect]; tmp.delegate = self; [self.view addSubview:tmp]; [tmp release]; } - (void)DoSomethingEveryFrame { NSLog(@"I'm the delegate! I'm doing printing!"); }
GifView中Timer每次執行都會列印一行
I'm the delegate! I'm doing printing!
故,RootViewController就知道Timer的每次執行了。