IOS Delegate代理實現

   在iOS 開發中, 搞清楚Delegate 是需要花些時間的。 Delegate  本來是軟件架構設計的一種理念。對於像手機這樣一個有限的設備,我們需要充分考慮到:內存要儘量省着用; 視圖之間的關係要清晰。 如果你所開發的App ,僅僅是一個demo,是體現不出架構優勢的。 但當你的App 需要處理海量數據, 而視圖之間的關係又頗爲複雜時,你將不得不考慮這些問題。 

視圖之間的關係,不僅僅是跳轉,更重要的是視圖之間數據的傳遞。當視圖A 發生變化時,如何將這個變化告知視圖B 呢?  舉個例子吧。

如下圖所示。

 

iOS Delegate 使用五步曲 - 悠悠音樂廣播 - 悠悠音樂廣播iPhone/iPad客戶端

 

這是一個計算器App,支持函數的圖形展示。 點擊右上角的按鈕,可彈出函數 列表。 這個列表是一個TableView;  函數圖形的展示是另一個視圖,我們稱之爲 GraphicView。  這個實例所展示的是: 當在Tableview選擇不同的函數時,函數的繪製圖形會隨之改變。這裏要解決的關鍵問題是, 如何將所選擇的函數告知 函數圖形視圖?  

先說明下,這是基於Storyboard 創建的工程。 工程本身有些複雜,我們不再從頭講起,這裏着重講解 @protocol 的使用。 

 通常,一個delegate的使用過程,需要經過五步:

1.     創建一個 delegate;

2.    委託者聲明一個delegate;

3.    委託者調用delegate內的方法(method);

4.    被委託者設置delegate,以便被委託者調用;

5.    被委託者實現Delegate 所定義的方法。

 

接下來,我們來一步一步實現:


1.1    第一步: 創建一個delegate

在 .h 文件中,  通過 @protocol 創建一個 delegate:

@protocol CalculatorProgramsTableViewControllerDelegate

 

@optional

- (void)calculatorProgramsTableViewController:

    (CalculatorPorgramTableViewController *)sender

                                 choseProgram:(id)program;

@end

 

代碼解釋:

@protocol CalculatorProgramsTableViewControllerDelegate

用來創建一個delegate。  這個delegate 中有一個方法: 

 

(void)calculatorProgramsTableViewController

@optional 表明,這個方法是不要求一定實現,是可選的。

 

小貼士:

這裏需明確一個概念, 雖然通過@protocol 定義了一個delegate,但不能說, delegate 就是protocol。  前面提到過,delegate是一種架構設計模式。 在iOS中,它是通過@protocol 來實現的。


1.2    第二步: 委託者聲明一個delegate

 

在TableView 的 .h 文件中 (CalculatorProgramsTableViewController.h), 將之前創建的delegate 通過@property 進行聲明。 代碼如下:

@interface CalculatorProgramsTableViewController : UITableViewController

...

// Define a property delegate

@property (nonatomic, weak) id<CalculatorProgramsTableViewControlerDelegate>

                            delegate;

...

@end

添加這幾行代碼後 , TableView 便擁有了Delegate。 有了Delegate, TableView就可以發消息了。 僅僅是可以發消息了,但還沒有發。 下一步,Tableview 開始發送消息。

 

 1.3    第三步:委託者調用delegate內的方法

我們的目標是:  當在TableView 上選擇不同的函數時, TableView 將這個所選定的函數,告知繪製函數圖形的GraphicView。

這一步,TableView  通過調用delegate的方法,發送消息。代碼實現如下:

 

#progma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView

    didSeelectRowAtIndexPath:(NSIndexPath *)indexPath

{

  id program = [self.programs objectAtIndex:indexPath.row];

  [self.delegate calculatorProgramsTableViewController:self

                                          choseProgram:porgram];

}

 

代碼解釋:

注意到 高亮部分的 self.delegate 了吧。 UITableView 就是通過這個之前定義的delegate 發送消息的。具體做法是: UITableViewController 調用delegate 中所定義的函數。通過這個函數的調用,  實現了消息的發送。但發到哪裏去了,還不得而知。這是因爲, self.delegate 還沒賦值呢。  

接下來,要做的是: 將  self.delegate  設置爲GraphicView。 

 

1.4     被委託者設置delegate,以便被委託者調用;
 

前面談到, UITableViewController 中的self.delegate 還沒有賦值。既然TableView 想把值傳給Graphicview,  那就應該在calculatorGraphViewController.m 文件中設置delegate。 也就是說,讓Graphicview 成爲Tableview的delegate。 

 代碼如下:

 

@implementation CalculatorGraphViewController

...

- (void)prepareForSegue:(UIStoryboardSegue *)segue

                 sender:(id)sender

{

  if ([segue.identifier isEqualToString:@"Show Favorite Graphics"]) {

    NSArray * programs = [[NSUserDefaults standardUserDefaults]

                         objectForKey:FAVORITES_KEY];

    [segue.destinationViewController setPrograms:programs];

[segue.destinationViewController setDelegate:self]; 

// set delegate

  }

}

 

代碼解釋:

但點擊Graphicview 右上角的button 時, 會彈出一個Tableview。同時,在這段代碼的最後一行,將CalculatorGraphViewController 設置爲Tableview 的delegate。 

通過這個設置, Tableview便可以調用Graphicview 所遵循的delegate 的的方法。 

Delegate 的這個方法還沒實現呢,  趕緊實現它吧。


1.5    被委託者實現Delegate 所定義的方法。

 

還記得那個神祕的 <> 吧。 通過以下代碼,讓GraphicViewController 來遵循這個delegate。  

// .h to implement the protocol

@interface CalculatorGraphViewController :NSObject 

     <CalculatorProgramsTableViewControllerDelegate>

...

@end

 

這是delegate使用的最後一步了, 我們在segue的controller 文件中,實現這個protocol所定義的方法。代碼如下:

// implement delegate method

- (void)calculatorProgramsTableViewController:(CalculatorProgramsTableViewController *)sender

                                chooseProgram:(id)program

{

  self.calculatorProgram = program;

}


1.6    小結

通過以上delegate 五部曲的演示,我們對delegate的機制,清楚些了吧。 Delegate 實現了不同視圖之間的數據交互。 Delegate 屬於事件驅動的範疇。只有當某一事件觸發時,delegate 才被調用。 

在Cocoa 框架中, 雖然數據存儲和訪問的方式有多種, 但delegate 所獨有的數據交互模式是無可替代的。

注:以上來自斯坦福iOS 教學。 這是一個經典的 delegate 應用案例。

發佈了18 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章