轉iOS中delegate、protocol的關係

來源:互聯網
上載者:User

標籤:class   blog   code   java   http   tar   

 iOS中delegate、protocol的關係分類: iOS Development2014-02-12 10:47 277人閱讀 評論(0) 收藏 舉報delegateiosprocotolcategoryobject-c

 

        剛開始接觸iOS,對delegate、protocol這兩個概念比較模糊。參考了一些資料,記錄下來體會。

 

        1.protocol         protocol和interface的概念類似,是object-c文法的一部分。protocol就是一系列不屬於任何類的方法的列表。其中聲明的方法能被任何類實現。只在protocol中定義行為,在不同的情況下使用不同的實現。這種模式一般稱為代理模式。在iOS和OS X開發中,Apple採用了大量的代理模式來實現MVC中View和Controller的解耦。         如何定義protocol呢?         在聲明檔案(h檔案)中通過關鍵字@protocol定義,然後給出Protocol的名稱,方法列表,然後用@end表示Protocol結束。在@end指令結束之前定義的方法,都屬於這個Protocol。        
@protocol myProtocol <NSObject>@required- (int)add:(int) a and:(int)b;@optional- (int)minus:(int)a and:(int)b;@end
             這裡還有兩個關鍵字,@required和@optional,一個是必須實現的,一個是可選的。可以根據名字直接判斷。         如何使用這個protocol呢?
@interface text : NSObject<myProtocol>@end
             定義一個類來使用protocol,用角括弧(<...>)括起來的就是我們定義的protocol,如果要採用多個Protocol,可以在角括弧內引入多個Protocol名稱,並用逗號隔開即可。         在這個類的實現檔案中來實現方法:
@implementation text- (int)add:(int)a and:(int)b{    return a + b;}- (int)minus:(int)a and:(int)b{    if (a >= b) {        return a - b;    }    else        return b - a;}@end

           iOS中Protocol和Java語言中的interface很類似,如果一些類之間沒有繼承關係,但是又具備某些相同的行為,則可以使用Protocol來描述它們的關係。不同的類,可以遵守同一個Protocol,在不同的情境下注入不同的執行個體,實現不同的功能。Cocoa架構中大量採用了這種模式實現資料和UI的分離。例如UIView產生的所有事件,都是通過委託的方式交給Controller完成。根據約定,架構中尾碼為Delegate的都是Protocol,例如UIApplicationDelegate,UIWebViewDelegate等。         2.delegate         delegate和protocol沒什麼關係,Delegate本身應該稱為一種設計模式。是把一個類自己需要做的一部分事情,讓另一個類(也可以就是自己本身)來完成。在執行一個類的方法的時候,想在這個方法裡面跳到另外一個類執行另外一個類的方法,就可以把delegate設定為另外一個類。         舉個例子:如果我在工作的時候想知道某場nba比賽的結果和喜歡的球星的資料,但是我在工作,不可以幹與工作無關的事情,我可以選擇發訊息給兩個人,讓他們查一下結果告訴我,一個去查比賽結果,一個去查喜歡球星的資料,然後我繼續工作。等過了一會,這兩個人查到想要的東西,把結果返回給我(通知我)。那麼這兩個人就是我的不同的委派物件。我.delegate = 某人。         如何使用delegate:用上面描述的例子來開始:        先定義一個 代理類 person1  person.h如下: 
#import <UIKit/UIKit.h>@protocol queryDelegate <NSObject>- (NSString *)query;@end@interface Person1 : UIViewController<queryDelegate>@end
         person.m
- (NSString *)query{    NSString * result = [NSString stringWithFormat:@"熱火贏太陽:103比98"];    return result;    }

        首先定義了協議與方法,代理類person1遵循這個協議,並且實現了委託方法。         同樣定義一個代理類person2,person2.h
#import <UIKit/UIKit.h>#import "Person1.h"@interface Person2 : UIViewController<queryDelegate>@end

        person2.m
- (NSString *)query{    NSString * data =[NSString stringWithFormat:@"詹姆斯的資料是37分9籃板3助攻" ];    return data;}

        代理類person2同樣遵循某個協議,並且實現了委託方法。         我們在介面上添加兩個button和 label,要求點擊上面的button,會在它下面的label上顯示今天nba  熱火vs太陽的比賽結果。點擊下面的button的時候,會在下面的lable顯示今天比賽的詹姆斯的資料;        添加完介面,給兩個button 設定action 給兩個label設定 outlet,ok,設定好之後,介面如下:                       delegateViewController.h:
#import <UIKit/UIKit.h>#import "Person1.h"#import "Person2.h"@interface delegateViewController : UIViewController@property (weak,nonatomic) id<queryDelegate> delegate;//聲明delegate- (IBAction)button1Action:(id)sender;- (IBAction)button2Action:(id)sender;@property (weak, nonatomic) IBOutlet UILabel *labelResult;@property (weak, nonatomic) IBOutlet UILabel *labelData;@end

             下面看delegateViewController.m:
#import "delegateViewController.h"@interface delegateViewController ()@end@implementation delegateViewController@synthesize labelData;@synthesize labelResult;.....- (IBAction)button1Action:(id)sender {        Person1 *pe1 = [[Person1 alloc] init];    self.delegate = pe1;//設定代理對象為person1    NSString * result = [self.delegate query];//通過委託變數調用委託方法     [labelResult setText:result];}- (IBAction)button2Action:(id)sender {    Person2 *pe2 = [[Person2 alloc]init];    self.delegate = pe2;//設定代理對象為person2    NSString* data = [self.delegate query] //通過委託變數調用委託方法      [labelData setText:data];    }


        這一步主要做的是聲明委託變數,設定代理,並且通過委託變數調用委託的方法。         執行結果:                  delegate概念的作用:        先看書上給出的經典說法:        1.The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.

        委託的主要價值是讓你可以在一個核心對象裡定製多個對象的功能特性。


        2.構建helper object 的工具 Helper Object are commonly used to add functionality to an existing class without having to subclass it.

        構建helper object,helper object用來對已有的類添加功能特性而不是通過子類繼承實現。          下面轉載一篇個人認為對delegate比較經典的解釋,原文地址:點擊開啟連結         Delegate本身應該稱為一種設計模式。是把一個類自己需要做的一部分事情,讓另一個類(也可以就是自己本身)來完成。
比如ClassC
@interface ClassC {    id delegate;}@end
             首先定義一個id類型的變數,名字叫做delegate。那麼ClassC的實現(.m檔案)裡就可以用delegate這個變數了。當然這裡完全可以用其它名字而不是delegate。        我們也可以這樣寫:
@interface ClassC {    ClassB *delegate;}@end
              這樣我們知道了delegate是一個ClassB,它就可以提供ClassB裡的方法。可以把一部分ClassC裡的工作放在ClassB裡去實現。這樣的寫法看起來是不是有點奇怪?或者應該寫成這樣?
@interface ClassC {    ClassB *classB;}@end

           .......按照上面這樣寫,delegate就沒有了。        所以說其實delegate只是一種模式,大家約定俗成,當把自己內部一部分實現暴露給另外一個類去做的時候,就叫實際做事的類為delegate。        為什麼會需要把內部實現提出來給另一個類做呢?最常見的目的就是為了在隱藏實現的前提下,提供一個自訂的機會。比如Apple提供的iOS SDK裡就有眾多的delegate,比如最常用的UITableView,我們沒法知道Apple怎麼重用UITableViewCell,怎麼處理UITableView裡Cell的增加、刪減,因為我們沒有源碼。但是我們可以通過實現Delegate的方法來控制一個UITableView的一些行為。UITableViewDataSource其實和delegate是一樣一樣的,只是由於意義不同換了個名字罷了。         protocol在此扮演了什麼角色呢?
        protocol是一種文法,它提供了一個很方便的、實現delegate模式的機會。
        比如寫UITableView的時候,Apple這麼幹        UITableView.m:
- (void)doSomething {[self blahblah];[self.delegate guruguru];//放到delegate中去執行這個guruguru函數[self blahblah];}
             delegate是我們寫的類,這個類如果可以被傳給UITableView做為其delegate,那唯一要求,就是它實現了
- (void)guruguru;
             這個方法。         如果我們把這個方法定義在一個protocol裡
@protocol XXXProtocol - (void)guruguru; @end

              就說明了,UITableView需要的delegate是一個conform to XXXProtocol的類。這就正好是id<XXXProtocol>表達的意思。         無論具體的類是什麼,它還有其它什麼方法,只要它conform to這個protocol,就說明它可以被傳給UITableView,作為它的delegate。那麼Apple為了讓我們知道這個protocol是delegate需要conform的protocol,它就把XXXProtocol改成了UITableViewDelegate。         這樣我們看到protocol的名字裡有Delegate,就知道這個protocol裡的函數是用來做自訂(Customization)的了。          delegate是對別的對象指標,按MVC一般最好賦值對象是Controller,它實現的是一種模式,它本身不是模式。Protocal是一組方法的定義。當id<protocal>定義為delegate時,就是要用別的對象即賦值的delegate去實現protocal裡的方法,這個過程使用的模式就是代理模式。Delegate類+protocal的話就保證了你另外實現的delegate類裡面必須有這個委託方法,但至於delegate類還可以幹其他事情。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.