2013年4月11日 星期四

Delegate & Protocal

詳細說明介紹我也不懂, 以我的理解就是
當前的Class想做某件事, 但我沒有能力做到, 拜託其他Class幫我做

例如我寫的這個範例
進入程式之後, 會看到一個UILabel, 顯示Hello World, 接著按push進入下一頁
在下一頁, 有一個UITextField讓你輸入自定文字, 按下Down之後就pop回上一頁, 並看到改變後的UILabel內容

SecondViewController.h
@protocol SecondControllerProtocal
@required
- (void)changeLabelText:(NSString *)str;
@end

@interface SecondViewController : UIViewController
@property (weak, nonatomic) id delegate;
@end
第一段是個簡單的protocal宣告, @protocal 後面接自定的protocal Name
@required, 表示這protocal一定要實作出來的方法, 沒實作的地方會有warning
另外還有修飾字@optional, 也就是選擇性的實現
不寫修飾字的話, 預設是@required

第二段宣告一個instance variable delegate,也就是代理


SecondViewController.m
- (IBAction)btnDown:(id)sender {
 [self.textField resignFirstResponder];
 [self.delegate changeLabelText:self.textField.text];
}
重點是[self.delegate changeLabelText:self.textField.text];這段
就字面翻譯我理解是 "我(SecondViewController)的代理 幫我做changeLabelText這件事"


ViewController.h
@interface ViewController : UIViewController <SecondControllerProtocal>
<SecondControllerProtocal>這表示 我們將要在ViewController實作SecondControllerProtocal的方法

ViewController.m
- (void)changeLabelText:(NSString *)str {
 self.lbl.text = [@"Hello " stringByAppendingFormat:@"%@!",str];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"Second"])
 {
        // Get reference to the destination view controller
        SecondViewController *second = [segue destinationViewController];
  
        // Pass any objects to the view controller here, like...
  second.delegate = self;
 }
}
changeLabelText是寫在SecondViewController.h中SecondControllerProtocal內表明一定要實作出來的方法, 實作內容為改變ViewController中UILable的文字內容

prepareForSegue不是討論範圍, 只看這內容兩行
SecondViewController *second = [segue destinationViewController];
second.delegate = self;
先取得SecondViewController的reference, 然後賦予property
可以把第二句理解為 SecondViewController的代理是我(ViewController)

配合上面SecondViewController.m說明的 "我的代理 幫我做 changeLabelText 這件事"
應該就不難理解了

沒有留言:

張貼留言