什么是 delegate
delegate是委托模式.委托模式是將一件屬于委托者做的事情,交給另外一個被委托者來處理.
一個標準的委托由以下部分組成:
我們需要用協議來申明哪些方法是被委托出去了.
@protocolMyUIViewDelegate- (void)func;@end
委托者里得有一個屬性代表被委托者, 注意這個屬性是弱引用.
@interfaceMyUIView:UIView@property(nonatomic,weak)id delegate;
被委托者需要聲明自己實現了委托里的協議.
@interfaceMyUIViewController:UIViewController@end
在被委托者里設置自己是委托者的被委托者.嘛,這句話是有些繞.
// viewcontroller. m中- (id)init{? ? MyUIView *myView = [[MyUIView alloc] init];//對MyUIView進行初始化myView.delegate=self;// 將MyUIViewController自己的實例作為委托對象self.view= myView; }
在委托者里調用委托的方法.
// MyUIView.m中- (void)doSomething{? ? [self.delegatefunc];? }
委托一般可以分成3種
傳遞事件就是A發生了什么事情, 希望B知道下, 然后B在自己的類里面要做出某些反應.典型的如
tableView:didSelectRowAtIndexPath:, 就是UITableView點擊了某個cell的時候, 希望其它類(通常是ViewController)響應這個點擊, 在點擊的時候跳轉到其他viewController之類的.
確定事件可執行是當A需要執行某個事件的時候, A不確定到底可執行, 這個時候希望B能回應下. 如tableView:shouldHighlightRowAtIndexPath:是UITableView詢問其它類要不要高亮顯示某個cell, 當返回NO的時候, 就UITableView就不會執行cell的高亮方法.
傳遞值是當A需要某個數據的時候, 由B來提供. 例子還是UITableView里的,tableView:cellForRowAtIndexPath:是需要某個cell的時候由其他類提供這個cell.
通常的委托用delegate做后綴.如
@protocol<#class#>Delegate
當你的委托的方法過多, 可以拆分數據部分和其他邏輯部分, 數據部分用dataSource做后綴. 如
@protocol<#class#>DataSource
委托的方法不是百分百必須實現的.
用required修飾的方法是必須實現的.協議默認聲明在其中的方法為必須實現的方法.
@protocolMyProtocol@required- (void)func;@end// 用的時候- (void)doSomething{? ? [_delegate <#func2#>];}
用optional修飾的方法可以不實現. 在用到的時候需要先判斷方法是否存在
@protocolMyProtocol@optional- (void)func;@end// 用的時候- (void)doSomething{if(_delegate respondsToSelector:@selector(<#func2#>)){? ? ? ? [_delegate <#func2#>];}}
當特定的事件發生時, 對象會觸發它注冊的委托方法.
委托的方法, 第一個參數是觸發它的對象,第一個關鍵詞是觸發對象的類名, 錯誤的狀態必須帶有error信息, 其他的參數看實際情況. 根據委托方法觸發的時機和目的, 使用should,will,did等關鍵詞.更具事件的狀態, 使用finish, fail, start等關鍵詞.
-(BOOL)tableView:(NSTableView*)tableView shouldSelectRow:(int)row;
finish表示一個事件已經完成, 通常情況下我們默認是成功.
- (void)<#class#>DidFinish<#event#>:(id)class
fail表示一個事件已經失敗了, 我們在這里需要返回錯誤的原因.
-(void)<#class#>:(id)classdidFail<#event#>:(NSError*)error
start標志一個事件的開始.
- (void)<#class#>DidStart<#event#>:(id)clas
should表示某事件將要開始.同意開始則返回YES, 否則返回NO
-(BOOL)<#class#>ShouldStart<#event#>:(id)class
1
通常的委托只支持一對一的委托, 但是在某些場景下, 我們希望有多個被委托者. 這種場景下可以考慮使用多播委托.
多播委托的實現類在XYMulticastDelegate,https://github.com/uxyheaven/XYQuick/tree/master/XYQuick/event/modules.
他是copy form XMPP的GCDMulticastDelegate.
每個多播委托的委托者類建議有以下的基本描述
// .h// 多播委托, 建議加上你的協議修飾: -(id )multicastDelggate;- (id)multicastDelggate;- (void)addDelegate:(id)delegate;- (void)removeDelegate:(id)delegate;- (void)removeAllDelegates;
實現文件里, 你需要這么寫
// .m- (void)addDelegate:(id)delegate{? ? [_multicastDelggate addDelegate:delegatedelegateQueue:dispatch_get_main_queue()];}- (void)removeDelegate:(id)delegate{? ? [_multicastDelggate removeDelegate:delegate];}- (void)removeAllDelegates{? ? [_multicastDelggate removeAllDelegates];}
父類實現部分協議, 子類實現部分協議.
詳情見
http://blog.csdn.net/uxyheaven/article/details/44261831
http://www.lxweimin.com/p/b6434c2997d1
http://leopard168.blog.163.com/blog/static/168471844201306114533858/