在.NET中都知道委托(delegate),通俗點的解釋就是可以將方法作為一個參數傳到另外一個方法中使用。
委托是一種引用方法的類型。一旦為委托分配了方法,委托將與該方法具有完全相同的行為。委托方法的使用可以像其他任何方法一樣,具有參數和返回值。在Object C中也同樣存在委托的概念,但是委托一般與協議(Protocol)同時使用,而且和.NET中的委托稍有區別
一. 定義委托(delegate)先定義一個協議(Protocol)
回顧一下上一篇所學的,先定義一個協議(Protocol) ProtocolName, 協議ProtocolName中定義了兩個方法: first ,second
具體的代碼如下:
#import <Foundation/Foundation.h> @protocol ProtocolName <NSObject> -(void) first; -(void) second; @end
上面定義的協議包含了兩個方法,返回值類型為特殊的類型void 。 void 在Object C中也被認為是一種特殊的返回值類型。
二. 定義兩個類遵循協議並實現方法
現在這里定義兩個類StudentA和StudentB來實現協議ProtocolName中的方法.
StudentA 實現的代碼如下:

#import <Foundation/Foundation.h> #import "ProtocolName.h" @interface StudentA : NSObject<ProtocolName> @end ----------------------------------------------------- #import "StudentA.h" @implementation StudentA -(void) first{ NSLog(@"StudentA---first"); } -(void) second{ NSLog(@"StudentA--second"); } @end
StudentB實現代碼如下:

#import <Foundation/Foundation.h> #import "ProtocolName.h" @interface StudentB : NSObject <ProtocolName> @end ------------------------------------------------------------ #import "StudentB.h" @implementation StudentB -(void) first{ NSLog(@"StudentB--first"); } -(void) second{ NSLog(@"StudentB--second"); } @end
我們注意到協議ProtocolName中的兩個方法並沒有使用@required 或者@optional 來修飾, 前面也提到過了,如果沒有使用任何修飾那么默認是@required,那么StudentA和StudentB必須實現這兩個方法,否則在編譯的時候就報錯。
三. 定義一個類用於代理
在上面定義了一個協議ProtocolName,然后新建一個Object C類Student,但是這個類並沒有去遵循協議ProtocolName 去實現其他的方法,而是通過委托來代理實現協議方法的調用。定義委托和定義屬性一樣,Student中的代理屬性代碼實現如下:

#import <Foundation/Foundation.h> #import "ProtocolName.h" @interface Student : NSObject{ id<ProtocolName> delegate; } @property (retain) id<ProtocolName> delegate; -(void) setMethod; @end --------------------------------------------- #import "Student.h" @implementation Student @synthesize delegate; -(void) setMethod{ NSLog(@"Student---setMethod"); [delegate first]; [delegate second]; } @end
在Student.h中定義了 id<ProtocolName> delegate; 這個其實就是類中的屬性,后來使用@property來修飾說明其自動實現了get set方法。這里不多說。關鍵看如何使用:
先創建一個StudentA的實例,同時創建一個Student的實力,將StudentA的實力賦值給delegate,這里相當於delegate代理了StudentA的實例。
Student *stu=[[Student alloc] init]; StudentA *stua=[[StudentA alloc] init]; StudentB *stub=[[StudentB alloc] init]; stu.delegate=stua; [stu.delegate first]; [stu setMethod]; stu.delegate=stub; [stu setMethod];
看到上面的代碼stu.delegate=stua, 這個就是委托代理。當stu調用方法setMethod方法時候,使用委托調用了方法first和方法second。
而代碼stu.delegate=stub, delegate又代理stub累,可以調用其中的方法first,second .
上面的測試結果如下:
2014-03-21 22:45:07.870 DelegateOS[577:303] StudentA---first 2014-03-21 22:45:07.872 DelegateOS[577:303] Student---setMethod 2014-03-21 22:45:07.872 DelegateOS[577:303] StudentA---first 2014-03-21 22:45:07.872 DelegateOS[577:303] StudentA--second 2014-03-21 22:45:07.873 DelegateOS[577:303] Student---setMethod 2014-03-21 22:45:07.873 DelegateOS[577:303] StudentB--first 2014-03-21 22:45:07.874 DelegateOS[577:303] StudentB--second