標籤:
最近看了一個代理的使用文檔,覺著寫的很好,記錄一下
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 應用案例。
iOS 代理的具體使用