日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

protocol(协议) 和 delegate(委托)也叫(代理)---辨析

發(fā)布時(shí)間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 protocol(协议) 和 delegate(委托)也叫(代理)---辨析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

protocol和delegate完全不是一回事。協(xié)議(protocol),(名詞)要求。就是使用了這個(gè)協(xié)議后就要按照這個(gè)協(xié)議來辦事,協(xié)議要求實(shí)現(xiàn)的方法就一定要實(shí)現(xiàn)。委托(delegate),(動(dòng)詞)助手。顧名思義就是委托別人辦事,就是當(dāng) 一件事情發(fā)生后,自己不處理,讓別人來處理。舉個(gè)淺顯的例子:我上班的工作主要內(nèi)容包括 (1)寫代碼(2)寫文檔(3)測試程序(4)接電話(5)會(huì)見客戶。(1)(2)我自己全權(quán)負(fù)責(zé),但是后面(3)(4)(5)我不想或者不方便自己做,所以我想找個(gè)助手(delegate)幫我做這些事,于是我定了一個(gè)招聘要求(Protocol),里寫明我的助手需要會(huì)做(3)(4)(5)這三件事。很快,我招到一個(gè)助手。即:我.delegate = 助手; 于是以后每當(dāng)我遇到需要測試程序或者接電話的活,我就把他轉(zhuǎn)交給助手(delegate)去處理,助手處理完后如果有處理結(jié)果(返回值)助手會(huì)告訴我,也許我會(huì)拿來用。如果不需要或者沒有結(jié)果,我就接著做下面的事。。protocol和java里interface的概念類似,是Objective-C語法的一部分。 定義protocol如下 C代碼 @protocol ClassADelegate - (void)methodA; - (void)methodB; @end 那么就是定義了一組函數(shù),這組函數(shù)放在一起叫作一個(gè)protocol,即 協(xié)議。函數(shù)是需要被實(shí)現(xiàn)的,所以如果對(duì)于class如下@interface ClassB <ClassADelegate> { } @end 就叫作ClassB conform(遵守)to protocol ClassADelegate,也就是說ClassB實(shí)現(xiàn)了這個(gè)協(xié)議, 也就是實(shí)現(xiàn)了這一組函數(shù)。有了上面這個(gè)頭文件,我們就可以放心作調(diào)用 C代碼 ClassB *b = [[ClassB alloc] init]; [b methodA]; [b methodB]; 而不用擔(dān)心出現(xiàn)unrecognized selector sent to instance這種錯(cuò)誤了。所以protocol就是一組函數(shù)定義,是從類聲明中剝離出來的一組定義。 C代碼 id<ClassADelegate> b = ...; (把實(shí)現(xiàn)類對(duì)象 賦值給 遵守此協(xié)議的擁有者 b ) [b methodA]; 這種用法也常見,b是一個(gè)id類型,它知道ClassADelegate這組函數(shù)的實(shí)現(xiàn)(即把實(shí)現(xiàn)類的對(duì)象賦值給b)。那么delegate是什么?其實(shí)和protocol沒有關(guān)系。Delegate本身應(yīng)該稱為一種設(shè)計(jì)模式。 是把一個(gè)類自己需要做的一部分事情,讓另一個(gè)類(也可以就是自己本身)來完成。 比如ClassC C代碼 @interface ClassC { id delegate; } @end 那么ClassC的實(shí)現(xiàn)(.m文件)里就可以用delegate這個(gè)變量了。 當(dāng)然這里完全可以用其它名字而不是delegate。我們也可以這樣寫 C代碼 @interface ClassC { ClassB *delegate; } @end 這樣我們知道了delegate是一個(gè)ClassB,它就可以提供ClassB里的方法。 可以把一部分ClassC里的工作放在ClassB里去實(shí)現(xiàn)。 這樣的寫法看起來是不是有點(diǎn)奇怪?或者應(yīng)該寫成這樣? C代碼 @interface ClassC { ClassB *classB; } @end … delegate沒有了… 所以說其實(shí)delegate只是一種模式,大家約定俗成,當(dāng)把自己內(nèi)部一部分實(shí)現(xiàn)暴露給另外一個(gè)類去做的時(shí)候,就叫實(shí)際做事的類為delegate(即助手)。為什么會(huì)需要把內(nèi)部實(shí)現(xiàn)提出來給另一個(gè)類做呢? 最常見的目的就是為了在隱藏實(shí)現(xiàn)的前提下,提供一個(gè)自定義的機(jī)會(huì)。 比如Apple提供的iOS SDK里就有眾多的delegate,比如最常用的UITableView, 我們沒法知道Apple怎么重用UITableViewCell,怎么處理UITableView里Cell的增加、刪減,因?yàn)槲覀儧]有源碼。 但是我們可以通過實(shí)現(xiàn)Delegate的方法來控制一個(gè)UITableView的一些行為。(即把delegate方法實(shí)現(xiàn)) UITableViewDataSource其實(shí)和delegate是一樣一樣的,只是由于意義不同換了個(gè)名字罷了。protocol在此扮演了什么角色呢? protocol是一種語法,它提供了一個(gè)很方便的、實(shí)現(xiàn)delegate模式的機(jī)會(huì)。 比如寫UITableView的時(shí)候,Apple這么干UITableView.m C代碼 - (void)doSomething { [self blahblah]; [self.delegate guruguru]; [self blahblah]; } delegate是我們寫的類,這個(gè)類如果可以被傳給UITableView做為其delegate,那唯一要求,就是它實(shí)現(xiàn)了 - (void)guruguru; 這個(gè)方法。如果我們把這個(gè)方法定義在一個(gè)protocol里 C代碼 @protocol XXXProtocol - (void)guruguru; @end 就說明了,UITableView需要的delegate是一個(gè)conform to XXXProtocol的類。 這就正好是id<XXXProtocol> 表達(dá)的意思。 無論具體的類是什么,它還有其它什么方法,只要它c(diǎn)onform to這個(gè)protocol, 就說明它可以被傳給UITableView,作為它的delegate。那么Apple為了讓我們知道這個(gè)protocol是delegate需要conform的protocol, 它就把XXXProtocol改成了UITableViewDelegate這樣我們看到protocol的名字里有Delegate,就知道這個(gè)protocol里的函數(shù)是用來做自定義(Customization)的了。來源:http://haoxiang.org/2011/08/ios-delegate-and-protocol/Protocol 的其它問題1. 使用時(shí)為什么要加上 iOS.delegate = self物件名稱.delegate = self,是在採用任何協(xié)定時(shí) 一定會(huì)看到的一行程式碼,由于定義協(xié)定的類別并不需要實(shí)作協(xié)定內(nèi)的方法,因?yàn)閷?shí)作的部份是由採納協(xié)定的類別來實(shí)作,但是它又必須要知道是由哪一個(gè)類別來實(shí)作,因此我們必須要把採納協(xié)定類別的 instance 交給定義協(xié)定的類別,讓它來使用。 另一方面并不是任何類別都可以將 instance 傳給定義協(xié)定的類別來使用,其原因是,我們?cè)诙x此協(xié)定的類別里有宣告 delegate 變數(shù)時(shí),有限定它必須要採納此協(xié)定(id delegate)如果沒有採用該協(xié)定就將 instance 傳給定義該協(xié)定的類別,Xcode 同樣會(huì)發(fā)出警告訊息。2. 為什么協(xié)定的生效位置不能寫在建構(gòu)式中協(xié)定的生效位置寫在建構(gòu)式中,并不會(huì)造成程式編譯上的任何問題,因?yàn)檫@是屬于邏輯上的錯(cuò)誤,協(xié)定要正常生效它必須要知道實(shí)作它方法的類別的 instance,如果將生效的位置寫在建構(gòu)式中,在建立定義此協(xié)定的形態(tài)的變物件時(shí),它的確會(huì)去觸發(fā)此協(xié)定內(nèi)的方法,但是由于并沒有給它實(shí)作此協(xié)定方法類別的 instance,因此不會(huì)有任何效果產(chǎn)生,反之,如果一定要將生效的位置寫在建構(gòu)式中,那么在初始化時(shí)就必須要設(shè)定好 delegate 才行,也就是使用初始化的方法函式里還必須要帶入一個(gè)參數(shù)物件好指定給 delegate。3. 在定義協(xié)定時(shí)同時(shí)也可以採用其他的協(xié)定如果在定義協(xié)定時(shí)同時(shí)又採用其他的協(xié)定,這會(huì)導(dǎo)致之后採納此協(xié)定的類別,它必須同時(shí)實(shí)作出兩個(gè)協(xié)定內(nèi)的方法,同樣地,你也可以利用此方式來擴(kuò)充那些已經(jīng)存在的協(xié)定。 C代碼 @protocol FurnaceDelegate <其它可能的協(xié)定名稱> 4. 使用 @optional 提供選擇性的實(shí)作@optional,如同它字面上的意義,在 @optional 之后的方法都可以是選擇性的實(shí)作,在定義協(xié)定時(shí)使用此方法,可以讓之后採納此協(xié)定的類別不一定要完全實(shí)作出協(xié)定內(nèi)的所有方法。 C代碼 @protocol FurnaceDelegate - (void)whenCalledDelegeteFunction; @optional -(void)optionalDelegeteFunction; @end






delegate ?protocol 是objective-c 語法的一部分 但他們兩個(gè)卻完全不是一回事。主要是我們經(jīng)常在同一個(gè)文件里見到這兩個(gè)東西

protocol(協(xié)議)我的理解就是定義這么一個(gè)東西。以后就按這里的規(guī)定來辦事。

delegate(委托) ?就是把事情委托給別人去辦?

@required 就是必須去辦的。比如UITableView ?delegate里面的:

-(NSInteger)tableView:(UITableView?*)tableView numberOfRowsInSection:(NSInteger)section

這個(gè)就是必須要實(shí)現(xiàn)的方法

@optional則是可做或不做。比如TUIableView ?delegate 里面的:

-(void)tableView:(UITableView?*)tableView didSelectRowAtIndexPath:(NSIndexPath?*)indexPath

這個(gè)就是可要可不要

?

關(guān)于delegate ?protocol 網(wǎng)上有一個(gè)例子講的非常形象:

? ? ? ? ? ?我上班的工作主要內(nèi)容包括 (1)寫代碼(2)寫文檔(3)測試程序(4)接電話(5)會(huì)見客戶

(1)(2)我自己全權(quán)負(fù)責(zé),但是后面(3)(4)(5)我不想或者不方便自己做,所以我想找個(gè)助手(delegate)幫我做這些事,于是我定了一個(gè)招聘要求(Protocol),里寫明我的助手需要會(huì)做(3)(4)(5)這三件事。很快,我招到一個(gè)助手。

? ? ? ? 即:我.delegate = 助手;

于是以后每當(dāng)我遇到需要測試程序或者接電話的活,我就把他轉(zhuǎn)交給助手(delegate)去處理,助手處理完后如果有處理結(jié)果(返回值)助手會(huì)告訴我,也許我會(huì)拿來用。如果不需要或者沒有結(jié)果,我就接著做下面的事。。

下面實(shí)現(xiàn)一個(gè)簡單的protocol?

在DelegateTest.h里實(shí)現(xiàn)protocol?

//定義protocol 協(xié)議 #import <UIKit/UIKit.h>@protocol DelegateTestDelegate; @interface DelegateTest : NSObject {id<DelegateTestDelegate> delegate; } @property(nonatomic,assign)id<DelegateTestDelegate> delegate; @property(nonatomic,assign)NSInteger nb; -(void)printPublic; //公開 @end//協(xié)議里的方法 @protocol DelegateTestDelegate<NSObject>-(void)print:(NSInteger)number; //如果別的類也用到了這個(gè)protocol 那么就可以直接調(diào)用了。 -(void)print; @end

DelegateTest.m 文件

#import "DelegateTest.h"@interface DelegateTest ()@end@implementation DelegateTest @synthesize delegate; @synthesize nb;//如果這個(gè)類是基于UIControllView的話??梢灾苯釉赩iewDidLoad里面調(diào)用。那么效果也是一樣的 這里就相當(dāng)于別的類里調(diào)用這個(gè)方法。起到激活的作用 -(void)printPublic {[delegate print];[delegate print:nb]; }@end

?

ViewController.h 文件

#import <UIKit/UIKit.h> #import "DelegateTest.h" @interface ViewController : UIViewController<DelegateTestDelegate> //這里的DelegateTestDelegate也就相當(dāng)于UITableView里的UITableViewDelegate {DelegateTest *delegateTest; }@property (nonatomic, assign)DelegateTest *delegateTest; @end

ViewController.m?文件

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController @synthesize delegateTest;- (void)viewDidLoad {[super viewDidLoad];delegateTest = [[DelegateTest alloc]init];[delegateTest setDelegate:self]; //設(shè)置代理[delegateTest printPublic ]; //選擇調(diào)用delegateTest 里的這個(gè)方法。然后就可以調(diào)用下面的print了。也就相當(dāng)于把print給激活了// Do any additional setup after loading the view, typically from a nib. }- (void)viewDidUnload {[super viewDidUnload];// Release any retained subviews of the main view. }//調(diào)用DelegateTest protocol 里面的方法 -(void)print {NSLog(@"qingjoin print succeed"); } -(void)print:(NSInteger)number {NSLog(@"%d",number); }- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); }@end 實(shí)現(xiàn)協(xié)議的步驟
1? ? //delegate,遵守協(xié)議

? ? //1, 定義協(xié)議擁有者:說明delegate對(duì)象是MaryProtocol類型的協(xié)議

? ? id <MaryProtocol>? delegate;//讓擁有者(使用者) 遵守協(xié)議(先定義)

?

? ? //2,賦值協(xié)議擁有者:將當(dāng)前對(duì)象 賦值 給協(xié)議擁有者

? ? delegate = curDelegate;

?













轉(zhuǎn)載于:https://www.cnblogs.com/iOS-mt/p/4103218.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的protocol(协议) 和 delegate(委托)也叫(代理)---辨析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。