轉:ios delegate

首先,你們應該都明白的是委託是協議的一種,顧名思義,就是委託他人幫本身去作什麼事。也就是當本身作什麼事情不方便的時候,就能夠創建一個委託,這樣就能夠委託他人幫本身去實現什麼方法。

其次,我簡單的總結了一下本身用到的委託的做用有兩個,一個是傳值,一個是傳事件。
1.所謂傳值常常用在b類要把本身的一個數據或者對象傳給a類,讓a類去展現或者處理。(切分緊耦合,和代碼分塊的時候常常用)
2.所謂傳事件就是a類發生了什麼事,把這件事告訴關注本身的人,也就是委託的對象,由委託的對象去考慮發生這個事件後應該作出什麼反映。(這個常常見,例如在異步請求中,界面事件觸發數據層改變等等)
3.利用委託賦值,這種方法感受是爲了避免暴露本身的屬性就能夠給本身復值,並且這樣更方便了類的管理,只有在你想要讓別人給你賦值的時候才調用,這樣的賦值更可控一些。(例如tableView中的委託(dateSource)中常見)。

最後,我想分享一下在使用委託的時候的一些心得和注意事項。

心得:delegate的命名要準確,儘可能看名字就知道用法。delegate和通知有的用法有些象,可是前者是單對單的,後者是單對多的狀況。
注意:在dealloc要把delegate至爲nil,還有就是delegate設置屬性的時候要用assign,不要用retain。
 
委託

在IOS中委託經過一種@protocol的方式實現,因此又稱爲協議.協議是多個類共享的一個方法列表,在協議中所列出的方法沒有響應的實現,由 其它人來實現.這叫比如我想買個手機,因此我有個buyIphone 方法,可是我不知道誰那買手機,因此把這個需求發佈出去(好比公佈在網站上),若是有賣手機的商人(也就是說他能實現buyIphone這個方法)看到, 他就會接受個人委託,(在商人本身的類中實現<XXXdelegate>),那麼個人委託對象就指向了這個商人..當我要買手機的時候,直接 找他就好了.php

例如:ios

複製代碼
@protocol MyDelegate
-(void)buyIphone:(NSString *)iphoneType money:(NSString *)money; @end @interface My : NSObject { id<MyDelegate> deleage; } @property(assign,nonatomic)id<MyDelegate> delegate; @end
複製代碼

代碼中聲明瞭一個協議 名叫Mydelegate,在其中有一個buyIphone方法,即一個委託項。當我要購買手機的時候只須要經過delegate 調用 BuyIphone方法便可.objective-c

以下:編程

-(void)willbuy
{
    [delegate buyIphone:@"iphone 4s" money:@"4888"]; }

我沒必要關心誰現實了這一委託,只要實現了這個委託的類,而且buyIphone是聲明的委託中必須實現的方法,那麼就必定可以獲得結果.設計模式

例如:商人類實現了這一委託(用<Mydelegate>表示實現)iphone

#import <Foundation/Foundation.h>
#import "My.h" @interface Business : NSObject<MyDelegate> @end

而後在 @implementation Business 中調用 buyIphone方法異步

複製代碼
#import "Business.h" @implementation Business -(void)buyIphone:(NSString *)iphoneType money:(NSString *)money { NSLog(@"手機有貨,這個價錢賣你了,發貨中!!"); } @end
複製代碼
委託是 Cocoa中最簡單、最靈活的模式之一。委託是指給一個對象提供機會對另外一個對象中的變化作出反應或者影響另外一個對象的行爲。其基本思想是:兩個對象協同 解決問題。一個對象很是普通,而且打算在普遍的情形中重用。它存儲指向另外一個對象(即它的委託)的引用,並在關鍵時刻給委託發消息。消息可能只是通知委託 發生了某件事情,給委託提供機會執行額外的處理,或者消息可能要求委託提供一些關鍵的信息以控制所發生的事情。
4 天前 上傳下載附件 (18 KB) 委託方法一般包括3種動詞:should、will、did。

should表示一個動做發生前,一般帶有返回值,能夠在動做發生以前改變對象狀態。
will在動做發生前,委託能夠對動做作出響應,但不帶有返回值。
did在動做發生後作出的響應。

從方法的定義咱們不難看出委託模式可以起到兩方面的做用:

第一:委託協助對象主體完成某項操做,將須要定製化的操做經過委託對象來自定義實現,達到和子類化對象主體一樣的做用。
第二:事件監聽,委託對象監聽對象主體的某些重要事件,對事件作出具體響應或廣播事件交給須要做出響應的對象。

我的理解採用委託模式的好處在於:

一、避免子類化帶來的過多的子類以及子類與父類的耦合
二、經過委託傳遞消息機制實現分層解耦

委託模式的實現思路:

一、一般是在對象主體包含一個委託對象的弱引用:
@interface A : NSObject
{
IBOutlet id delegate;
} -(id) delegate;
-(void) setDelegate:(id)obj;
二、委託對象的實現有兩種方式:正式協議和非正式協議,對象主體在協議中定義委託方法,委託對象能夠選擇實現其中某些委託方法,所以若是經過正式協議定義委託方法須要使用@option。
@protocol NSSearchDelegate
@option
-(void)didSearchFinish:(*NSNotification) aNotification;
@end
三、鏈接對象主體和委託,無非就是經過setDelegate:(id)obj來實現。

四、觸發委託方法。

昨天作了一個demo,用到了簡單代理。ide

delegate是ios編程的一種設計模式。咱們能夠用這個設計模式來讓單繼承的objective-c類表現出它父類以外類的特徵。昨天這個代理實現以下:動畫

 

類GifView是繼承自UIView的,它加載在RootViewController上來經過一個Timer播放動畫。同時,RootViewController須要知道Timer的每次執行。網站

代碼以下。

首先,定義GifView,在其頭文件中定義代理EveryFrameDelegate,同時聲明方法- (void)DoSomethingEveryFrame;

複製代碼
#import <UIKit/UIKit.h>

@protocol EveryFrameDelegate <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的每次執行了。

 
 
 
 

作程序時,常常會碰到這樣一種狀況:在對象A中有一個對象B,在B中作某個操做時須要調用A對象的某個方法。這時,咱們就須要用代理機制,也叫委託機制。

還記得剛接觸面向對象的時候,竟然在B對象中又alloc了一個A對象,發現執行方法時沒有works,那時不理解新alloc的對象和原來的對象A不是一個東東。
今天專門補習了一下哈,在網上找了一些資料,綜合了一下,寫了這篇菜鳥教程。

委託代理(delegate), 顧名思義,把某個對象要作的事情委託給別的對象去作。那麼別的對象就是這個對象的代理,代替它來打理要作的事。反映到程序中, 首先要明確一個對象的委託方是哪一個對象,委託所作的內容是什麼。委託機制在不少語言中都用到的,這只是個通用的思想,網上會有不少關於這方面的介紹

下面以一個簡單的例子介紹一下委託:

1、新建iPhone項目DelegateDemo;

2、添加UIView類ViewA;

3、ViewA.h的內容以下:

  1. #import <UIKit/UIKit.h>  
  2.   
  3. @protocol <a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a>; //申明代理協議  
  4.   
  5. @interface ViewA : UIView {  
  6.     id <<a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a>> _viewADelegate;  
  7. }  
  8.   
  9. @property (nonatomic, assign) id viewADelegate; //定義代理的屬性,同時要在.m加中  
  10.   
  11. @end  
  12.   
  13. //代理協議的內容  
  14. @protocol <a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a> <NSObject>  
  15. - (void)<span style="color:#008080">viewACallBack</span>;  
  16. @end  
  17.   
  18. View.m中:  
  19. <span> </span>@synthesize viewADelegate = _viewADelegate;  

3、在DelegateDemoViewController.m中:

- (void)viewDidLoad {
	ViewA *viewA = [[ViewA alloc] initWithFrame:CGRectMake(50, 100, 200, 100)];
	viewA.viewADelegate = self; //設置viewA的代理爲當前對象本身
	[self.view addSubview:viewA];
	[viewA release];
	[super viewDidLoad];
}

- (void)viewACallBack {
	NSLog(@"Hi, I am back!");
}

4、

點擊此處下載示例。

相關文章
相關標籤/搜索