徹底理解Objective-C:協(xié)議(protocol),代理(delegate)

許多同學(xué)在第一次接觸Objective-C里面的代理,協(xié)議,代理協(xié)議這些概念,很容易被搞暈.
再加上初次接觸 Objective-C 類的property等寫法看著比較陌生,更加劇了理解難度.
本文的目的就是,讓你徹底理解協(xié)議,代理,以及他們的使用場景.
我將要用一個大家都熟悉的場景來講解.

導(dǎo)演可以拍電影,調(diào)教演員,也可以進(jìn)入到后期制作.導(dǎo)演也可以招聘"助理",幫他干后期制作的事情.

我們先寫看協(xié)議.(protocol)協(xié)議=protocol


協(xié)議是什么? 協(xié)議就是一紙協(xié)議,聽著好像廢話,你可以從許多角度來看協(xié)議:

  • 協(xié)議是某種約定(或許多約定的組合)
  • 協(xié)議是雙方要遵守的東西.
  • 協(xié)議是許多小項的組合.
  • 協(xié)議是雙方的約定.
  • 協(xié)議有個協(xié)議名字
    那Objective-C里面呢, 協(xié)議就是”功能的集合”===>”方法的集合” ,也就是”能力清單”.

協(xié)議就是帶名字的能力清單

我們先拋開Objective-C里面那些ViewController, DataSource, View那些概念,看上面說的具體的協(xié)議例子:

 # 影視行政助理協(xié)議(協(xié)議的名字) # 

功能列表:

  1:能尋找合適的膠片沖洗廠,進(jìn)行膠片的沖洗(必須).

  2:后期音頻合成,可以將錄制好的音頻合成到膠片里面(必須).

  3:需找海報制作商(必須).

  4:負(fù)責(zé)片場治安秩序(非必須)


所以,這個協(xié)議名字叫

”影視行政助理協(xié)議”

這是一紙清單.這個清單有4個項目(功能/方法),其中前3個是必須的.
協(xié)議有協(xié)議名字,有清單(方法列表,或者說功能列表)

協(xié)議就是”協(xié)議就是帶名字的能力清單”.


下面再說代理().(delegate)

上面提到”協(xié)議是雙方的約定”,否則單單只存在一份協(xié)議是沒有意義的(但是沒有錯),我們來看看協(xié)議涉及到的雙方.

  • 導(dǎo)演(Director):導(dǎo)演很忙,(實際上,那份協(xié)議就是導(dǎo)演自己編寫的),因為他要把主要精力放到”藝術(shù)創(chuàng)作”上,把重要的瑣事”代理”出去(這里的代理是動詞),或者說把重要的瑣事讓”代理”去干(這里的代理是名詞),為了便于理解,我們用名詞這種方式.
    我們再看看實際情況下,影視圈的情況:
  • oldStreet:(老街)男,一個長期混跡影視圈的能人,行政能力很強(qiáng),快50了,
    做事老派,不上網(wǎng),沒有微信,喜歡通過人脈干事,上面那4個活他都能干,尤其負(fù)責(zé)片場治安那個.
  • newSchool:(新校)女,剛剛畢業(yè)的電影學(xué)院學(xué)生,20出頭,新潮人類,離開微信不能活那種,需要找工作.上面那個協(xié)議里面的事,她能干3個,負(fù)責(zé)片場治安秩序?還是算了吧.

現(xiàn)在,這兩人都來應(yīng)聘,都符合條件(就是說這兩人都可以干協(xié)議里面規(guī)定必須能干的事情),在Objective-C里面,我們說”這兩人都實現(xiàn)了這個協(xié)議”.

而導(dǎo)演這邊呢,以前是孤家寡人,累的要死,現(xiàn)在有了助理了,對吧? ,以前導(dǎo)演可以這么自我介紹(導(dǎo)演的屬性):

”XX導(dǎo)演,男,35歲,恐怖片導(dǎo)演,只做恐怖片,不是北京人,未婚”.

但是現(xiàn)在你要這么介紹了:

”XX導(dǎo)演,男,35歲,恐怖片導(dǎo)演,只做恐怖片,不是北京人,未婚,我的影視后期制助理是誰誰誰”.

如果導(dǎo)演太忙了,他可能還需要其他的人幫他干活,比如劇本醫(yī)生,那就要這么介紹:

”XX導(dǎo)演,男,35歲,恐怖片導(dǎo)演,只做恐怖片,不是北京人,未婚,我的行政助理是誰誰誰,我的劇本醫(yī)生是誰誰誰”.

這段意思是說,導(dǎo)演可以超過一個代理.我們把情況搞簡單,先只給他一個代理(影視后期制作).
導(dǎo)演的影視后期制作是"某某某",這句話的復(fù)雜版本是:

某某某可以干"影視行政助理協(xié)議"這個協(xié)議里面規(guī)定的必須干的事情,導(dǎo)演的"導(dǎo)演的影視后期制作代理"被設(shè)置成"某某某",<br/>
導(dǎo)演可以安排助理干"影視行政助理協(xié)議"里面的任何事情了.

我們可以看到, 是 協(xié)議 將本來沒有關(guān)系的兩方(導(dǎo)演,某某某)聯(lián)系了起來.
下面是filmAssistantProtocol.h 文件,就是協(xié)議文件.

@protocol 開頭,
以@end結(jié)尾.
//filmAssistantProtocol.h
@protocol filmAssistantProtocol   //協(xié)議名字

@required
/*
 1:能尋找合適的膠片沖洗廠,進(jìn)行膠片的沖洗(必須).
 2:后期音頻合成,可以將錄制好的音頻合成到膠片里面(必須).
 3:需找海報制作商(必須).
 4:負(fù)責(zé)片場治安秩序(非必須)
 */

+(void) filmDeveloped;  //沖洗照片
+(void) audioProcess;   //音頻合成
+(void) posterMake ;   //海報制造

@optional
-(void) siteSecurity; //現(xiàn)成安保

@end

我們可以很清楚的看到,協(xié)議(protocol)就是一個協(xié)議名字+功能列表(實際就是方法列表)

然后看看導(dǎo)演這里的寫法(Director.h)

//
//  Director.h

#import <Foundation/Foundation.h>
#import "filmAssistantProtocol.h"

//#import "劇本醫(yī)生協(xié)議.h"

@interface Director : NSObject

@property (strong, nonatomic) NSString   *directorName;  //定義導(dǎo)演的名字

//

/*定義一個后期制作的代理 backAssistant,這個代理遵守 filmAssistantProtocol 這個
協(xié)議,即:這個后期制作的代理 應(yīng)該能干filmAssistantProtocol 這個協(xié)議里面定義的
功能集合
 
與通常我們見到的 
 @property(nonatomic, retain)  id <someProtocol>        delegate; 寫法其實是一回事.
                                      |                   |
                                      |                   |
                                      V                   V
 @property(nonatomic, retain)  id<filmAssistantProtocol> backAssistant;

*/

@property(nonatomic, retain) id<filmAssistantProtocol> backAssistant;

/*我們目前只有一個代理,如果需要其他代理(比如劇本醫(yī)生),將會是下面的寫法*/

//@property(nonatomic, retain) id<劇本醫(yī)生協(xié)議> 劇本代理人;

-(void) posterMake;  //印刷海報,導(dǎo)演自己也可以印刷海報
-(void) introMyself; // 導(dǎo)演自我介紹的方法.

@end

注意:與導(dǎo)演名字directorName并列的另外一個屬性是backAssistant,
backAssistant/后期制做代理

再看看一個newSchool的情況:



//
//  newSchool.h
//  Film
//
//  Created by Alex on 4/9/16.
//  Copyright ? 2016 Alex. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "filmAssistantProtocol.h"
@interface newSchool : NSObject<filmAssistantProtocol>  //實現(xiàn)了filmAssistantProtocol這個協(xié)議
@property (strong, nonatomic) NSString   *girlname;
//沖洗照片
-(void) filmDeveloped;
//音頻合成
-(void) audioProcess;
//海報制造
-(void) posterMake;
@end

我們看到, filmAssistantProtocol 出現(xiàn)了兩次,

  • Director.h ,可以理解成:[導(dǎo)演說,我要有個助理,能干后期制作那些事]
  • newSchool.h ,可以理解成:[一個畢業(yè)新手說,干后期制作那些事,我都能干]

最后的組合

 

//
//  ViewController.m
//

#import "ViewController.h"
#import "Director.h"
#import "newSchool.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"程序開始了");
    Director* oneDirector = [[Director alloc] init]; //初始化一個導(dǎo)演
    
    oneDirector.directorName = @"PeterJ";    // PeterJ ,彼得杰克遜,指環(huán)王導(dǎo)演,這樣讓你們讀代碼好記.

    [oneDirector introMyself];   //導(dǎo)演介紹自己,雖然有"assistant"這個屬性,但是還么有指定具體人.
    
    [oneDirector posterMake];   //導(dǎo)演自己也可以posterMake,因為他有這個方法.
    
    newSchool* oneGirl = [[newSchool alloc] init];  //定義一個新派的女學(xué)生,因為這個newSchool實現(xiàn)了那個協(xié)議,所以她就有那些能力.
    oneGirl.girlname = @"小花蝴蝶";
    
    //設(shè)置代理,把導(dǎo)演的后期制作代理設(shè)置成這個'小花蝴蝶',以后印海報那些事就交給小花蝴蝶干.
    /*
     我們在代碼里面常見的那種寫法
      XXX.delegate=self;
    或  
     
     XXX.delegate=yyy;
     與下面其實是一個意思.
     
     */
    
    oneDirector.backAssistant = oneGirl;    //把這個女孩指定為導(dǎo)演的那些干雜事的代理.
    
    [oneDirector introMyself];          //導(dǎo)演再次描述自己,backAssistant已經(jīng)有人了.
    
    [oneDirector.backAssistant posterMake]; //導(dǎo)演可以讓自己的backAssistant 去弄海報這事了.
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

運(yùn)行時候注意看Xcode的日志. 希望對你有幫助.


協(xié)議/代理的使用場景

從上面的描述可以看到, 協(xié)議和代理基本是一起使用的,是為了降低復(fù)雜度,
即:把某些功能"聚合"到一個協(xié)議里面去, 然后請代理干活.
你基本可以理解成一種設(shè)計模式,或者是一種架構(gòu)方法.

這種模式的常用做法,

  • 定義某一類的功能集合(協(xié)議),然后
  • 新的類實現(xiàn)協(xié)議里面的功能
  • 其他類,指定自己的代理是別人,讓別人干功能集合里面的某些事情

示范工程在:
https://github.com/tangyongjin/Film

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市扎瓶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌概荷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件误证,死亡現(xiàn)場離奇詭異,居然都是意外死亡愈捅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門灌具,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人譬巫,你說我怎么就攤上這事÷簦” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵瘪松,是天一觀的道長咸作。 經(jīng)常有香客問我宵睦,道長,這世上最難降的妖魔是什么壳嚎? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮说庭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘郑趁。我一直安慰自己,他們只是感情好寡润,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躲惰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪础拨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天诡宗,我揣著相機(jī)與錄音,去河邊找鬼塔沃。 笑死,一個胖子當(dāng)著我的面吹牛曙痘,可吹牛的內(nèi)容都是我干的边坤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼茧痒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旺订?” 一聲冷哼從身側(cè)響起弄企,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拘领,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后樱调,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體约素,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笆凌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了送悔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡欠啤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跪妥,到底是詐尸還是另有隱情,我是刑警寧澤声滥,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站纽疟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏憾赁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一蟆肆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晦款,春花似錦、人聲如沸缓溅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽股囊。三九已至,卻和暖如春更啄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锈死。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留待牵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓缨该,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贰拿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容