在.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