2012年2月20日 星期一

iOS學習_實作自己的delegate來傳值

在iOS開發過程中,我們會使用很多元件,比如UITableView、UIWebView等等,不管是什麼用途的元件,都有一個共同的特點,就是會有專屬的委任方法(delegate),而知道有哪些與學會怎麼用Apple提供的delegate是第一步。但如果是自己客制化的介面或邏輯,就可能需要自己實作屬於該架構的delegate。

自己寫之前,先想一下如果使用Apple的delegate是什麼情況?
1. 在h檔引用適當的protocol。
2. 依照引用的protocol,於m檔實作必須的方法。
3. 於m檔加入類似:self.delegate=self的程式碼。

所以,我們可以瞭解若是要一個delegate method完成值的傳遞必須具備以下內容:
1. 一個protocol定義檔。
2. 一個delegate method的執行或運算邏輯。
3. 一個引用上述protocol,並實作完成的程式檔。

以下圖來說明:

1. 紫色區塊:新建一個Objective-C protocol檔案,並定義相關方法。檔案命名為olaDelegate,並於內定義method1與method2兩個方法。

#import <Foundation/Foundation.h>
@protocol olaDelegate <NSObject>
@optional
- (void)method1:(NSString*)value1;
- (void)method2:(NSString*)value2;
@end


2. 綠色區塊:於須實作delegate的檔內(可能是任何類型,EX:UIViewController、NSOperation等)定義一動態型別變數,並執行delegate 方法來取得外部傳入的值,以撰寫需要的邏輯。
h檔

#import <Foundation/Foundation.h>
#import "olaDelegate.h"

@interface Operation :NSOperation
{
id<olaDelegate> delegate;
}
@property (nonatomic, assign) id<olaDelegate> delegate;
- (void)someMethod;
@end


m檔

-(void)someMethod
{
[delegate method1:@"ola"];
[delegate method2:@" a pay rise"];
}


3. 藍色區塊:引用protocol,並完成其實作。
h檔

@interface DropDocument_Table : UIViewController<olaDelegate>
{
........
}


m檔

-(void)init
{
Operation *op = [Operation alloc] init];
op.delegate = self;
}
-(void)method1:(NSString*)value1
{
//撰寫取得value1後的反應。
}
-(void)method2:(NSString*)value2
{
//撰寫取得value2後的反應。
}


所以程式跑的流程會是:由某一種方式觸發綠色區塊的SomeMethod後,將value1與value2透過method1與method2傳給藍色區塊,假設藍、綠色區塊都是UIView,那磨就可以完成兩個View的傳值,若是綠色區塊是NSOperation,則可以完成非同步傳輸後callback function的效果。


為什麼這樣可以進行傳值的動作?講到底,原因就是op.delegate = self;,在這程式把整個自己(self)傳給了op.delegate這一個動態型別,再於op內執行寫在self內的方法,來完成兩者交互的傳遞。

這樣的好處在於我們可以撰寫元件(綠色區塊),並透過protocol(紫色區塊)規定別人在使用我們的元件時必須實作哪些方法,而使用元件的人就可以將邏輯寫在自己內部(藍色區塊),並透過我們完成的元件來展現,就像是UITableView的感覺一樣。

4 則留言:

Atwood Liu的走馬燈 提到...
作者已經移除這則留言。
Atwood Liu 提到...

圖例說明很清楚:A宣告Delegate Protocol,B採用並實作Delegate Protocol,A再指定B的instance為delegate,傳值給B。
有大學iOS programming課程教材的水準。

ola的家 提到...

:D

匿名 提到...

看到這張圖 嚴格講綠色圖的部份 不應該叫 delegate 它是委託人 在IOS的開發網站上稱做delegating object, 藍色圖的部份才算是delegate,因為它才是真正實作被委託的protocol功能
雖然只是名稱的用法,但我自己在看覺得會被誤導

張貼留言