IOS中的協(xié)議Protocol與代理Delegate以及通知

Protocol和Delegate簡介

Protocol協(xié)議類似于Java中的接口,是一個自定義方法的集合闯团,讓遵守這個協(xié)議的類去是實(shí)現(xiàn)為了達(dá)到某種功能的這些方法晾虑,與Java接口不同的是協(xié)議中可以定義可選擇實(shí)現(xiàn)的方法。Delegate代理是一種設(shè)計(jì)模式仅叫,是一個概念帜篇,只不過在Objective-C中通過Protocol來進(jìn)行實(shí)現(xiàn),指的是讓其他類來通過本類中定義的協(xié)議代理方法‘遠(yuǎn)程’幫助實(shí)現(xiàn)一些操作诫咱,完成一些任務(wù)笙隙,本類會在合適的時機(jī)通過代理通知實(shí)現(xiàn)協(xié)議的遠(yuǎn)程類去做指定的任務(wù)。

通過協(xié)議實(shí)現(xiàn)代理模式的示例

協(xié)議代理來源的本類:

#import <UIKit/UIKit.h> 
/** * 定義協(xié)議 */
@protocol AccountDelegate <NSObject>

@required // 必須實(shí)現(xiàn)的方法坎缭,默認(rèn)是@required /** * 選中cell的代理事件 */
- (void) selectedCell:(NSInteger)index;

@optional // 非必須實(shí)現(xiàn)的方法 /** * 更新下拉菜單的高度 */
- (void) updateListH;

@end

@interface PopListTableViewController : UITableViewController

/** * 定義代理竟痰,委托其他類來幫助本類完成一些其他任務(wù)签钩,本類通過下面定義的delegate來通知其他實(shí)現(xiàn)上面協(xié)議的其他類 */
@property (nonatomic, weak) id<AccountDelegate>delegate;

@end

然后本類在實(shí)現(xiàn)中通過定義的delegate通知其他遵守協(xié)議的類去執(zhí)行某個方法:

// 通知代理,同時將cell的行號傳出去 [_delegate selectedCell:indexPath.row];

然后遵守協(xié)議的類就可以收到上面的通知自動執(zhí)行(注意是通知觸發(fā)的方法執(zhí)行,而不是手動調(diào)用方法)selectedCell這個方法了:

首先要在實(shí)現(xiàn)中聲明遵守上面的協(xié)議:

// 遵守AccountDelegate協(xié)議坏快,如果遵守多個協(xié)議用逗號隔開:<AccountDelegate, ...> @interface PopMenuViewController()<AccountDelegate>

實(shí)現(xiàn)協(xié)議方法:

/** * 實(shí)現(xiàn)協(xié)議方法铅檩,監(jiān)聽代理,代理通知來了后下面的方法會自動執(zhí)行,接收傳過來的參數(shù) */
- (void)selectedCell:(NSInteger)index {
    // 這里可以做一些事情莽鸿,也就是想委托當(dāng)前這個類要做的那些任務(wù)了     // ... }

問題1: Objective-C中的協(xié)議和java中的接口概念有何不同昧旨?

Objective-C中的協(xié)議和java中的接口非常類似,但Java中的接口規(guī)定實(shí)現(xiàn)接口的類必須要實(shí)現(xiàn)接口中定義的所有方法祥得,當(dāng)然默認(rèn)Objective-C協(xié)議中定義的方法也是要必須實(shí)現(xiàn)的兔沃,只不過Objective-C的協(xié)議里的方法有兩種類型:必選類型(@required)和可選類型(@optional)。必須類型是必須要實(shí)現(xiàn)的级及,而可選類型是根據(jù)需要選擇性實(shí)現(xiàn)的乒疏。默認(rèn)是必選類型。

問題2: OC中協(xié)議的概念以及協(xié)議中方法的默認(rèn)類型饮焦?
OC中的協(xié)議類似于Java中的接口怕吴,是一個功能方法的集合,但協(xié)議本身不是一個類不會自己去實(shí)現(xiàn)協(xié)議里的方法追驴,而是委托其他任何類去使用實(shí)現(xiàn)械哟,通常用來實(shí)現(xiàn)委托代理設(shè)計(jì)模式,實(shí)現(xiàn)不同類對象之間的事件消息通信殿雪。

協(xié)議中的方法默認(rèn)都是@required類型的暇咆,也就是使用該協(xié)議的類必須實(shí)現(xiàn)協(xié)議里的這些方法。而明確使用@optional修飾的方法可以被使用的類選擇性的去實(shí)現(xiàn)丙曙。

問題3: 什么是代理爸业?作用是什么?
代理是一種設(shè)計(jì)模式亏镰,又叫‘委托’扯旷,指的是一個類對象在某些特定時刻通知到其他類的對象去做一些任務(wù),但不需要獲取到那些類對象的指針索抓,兩者共同來完成一件事钧忽,實(shí)現(xiàn)不同對象之間的通信。

作用主要是大大減小了對象之間的耦合度逼肯,是代碼邏輯更加清晰有序耸黑,減少了框架復(fù)雜度,也便于代碼的維護(hù)擴(kuò)展篮幢。另外消息的傳遞過程可以有參數(shù)回調(diào)大刊,類似于Java的回調(diào)監(jiān)聽機(jī)制,大大提高了編程的靈活性三椿。

問題: 什么是推送消息缺菌?和Notification有什么不同葫辐?
消息推送指的是在App關(guān)閉不在前臺運(yùn)行時,向用戶發(fā)送App的內(nèi)部消息伴郁。消息推送通知和OC中的Notification通知機(jī)制不同耿战,推送的消息是給用戶看的,也就是可見的蛾绎,而通知機(jī)制是OC語言中類間通信的一種機(jī)制昆箕,基于觀察者模式,目的是觸發(fā)內(nèi)部事件租冠,減小類之間的耦合度鹏倘,而對用戶是不可見的。

推送消息的可見形式主要有以下幾種:

鎖屏界面的橫幅推送消息顽爹;
頂部通知欄的橫幅推送消息纤泵;
應(yīng)用圖標(biāo)上的代表消息數(shù)量的紅色數(shù)字;
菜單頁面彈出框提示镜粤;
播放聲音提示捏题;


60.png

iOS開發(fā)中有兩種類型的消息推送:本地消息推送(Local Notification)和遠(yuǎn)程消息推送(Remote Notification)。

本地消息推送: 本地推送很簡單肉渴,不需要聯(lián)網(wǎng)公荧,不需要服務(wù)器,由客戶端應(yīng)用直接發(fā)出推送消息同规,一般通過定時器在指定的時間進(jìn)行消息推送循狰。

遠(yuǎn)程消息推送: 遠(yuǎn)程推送過程略為復(fù)雜,需要客戶端從蘋果的APNS(Apple Push Notification Services)服務(wù)器注冊獲得當(dāng)前用戶的設(shè)備令牌并發(fā)送給應(yīng)用的服務(wù)器券勺,然后應(yīng)用的服務(wù)器才可以通過APNS服務(wù)器間接地向客戶端發(fā)送推送消息绪钥,期間難免會有延遲。

遠(yuǎn)程推送的具體流程如下圖所示关炼,開發(fā)中要和服務(wù)器合作共同完成:

App客戶端向APNS蘋果服務(wù)器發(fā)送設(shè)備的UDID和Bundle Identifier程腹;
APNS服務(wù)器對傳過來的信息加密生成一個deviceToken,并返回給客戶端儒拂;
客戶端將當(dāng)前用戶的deviceToken發(fā)送給自己應(yīng)用的服務(wù)器寸潦;
自己的服務(wù)器將得到的deviceToken保存,需要的時候利用deviceToken向APNS服務(wù)器發(fā)送推送消息社痛;
APNS服務(wù)器接收到自己服務(wù)器的推送消息時见转,驗(yàn)證傳過來的deviceToken,如果一致則將消息推送到客戶端褥影;
2.利用deviceToken進(jìn)行數(shù)據(jù)傳輸,推送通知

問題: 什么是Notification?什么時候用Delegate咏雌,什么時候用Notification凡怎?

Notification通知是Cocoa框架中基于觀察者模式實(shí)現(xiàn)的用于‘一對多’傳播消息的一種機(jī)制校焦。項(xiàng)目中的對象將它們自己或者其他對象添加到通知的觀察者列表里(這個過程又叫通知注冊),其中項(xiàng)目中的所有通知都有一個唯一的字符串標(biāo)識作為通知名唯一確定每個通知统倒,通知源也就是被觀察者可以創(chuàng)建通知對象并發(fā)送到通知中心寨典,通知中心找出所有注冊該通知的對象(觀察者),并將從被觀察者那里收到通知以消息的方式發(fā)送給所有的觀察者們房匆。被觀察者發(fā)送通知是一個同步過程耸成,即發(fā)送者在通知中心成功將該發(fā)送者之前的消息發(fā)送給所有觀察者之前不可以再次發(fā)送通知。另外通知觸發(fā)的代理方法都必須符合某個單一參數(shù)簽名約定浴鸿,代理方法的參數(shù)是一個通知對象井氢,參數(shù)里包含著通知名、被觀察者和一個包含其他額外信息的字典岳链。


65.jpeg

Delegate和Notification的主要區(qū)別在于前者是一對一的消息傳遞花竞,而后者是一對多的,可以根據(jù)這個特點(diǎn)在使用中進(jìn)行選擇掸哑。另外代理模式中约急,接受者reciever可以返回值給sender發(fā)送者,實(shí)現(xiàn)一種回調(diào)苗分,而觀察者模式中觀察者不可以返回值給被觀察者厌蔽,因此在需要實(shí)現(xiàn)回調(diào)時只能選擇代理模式。

其他問法:

delegate和notification的區(qū)別是什么摔癣?分別在什么情況下使用?
通知Notification和協(xié)議Protocol的不同之處

問題: NSNotification奴饮、Delegate、Block和KVO的對比供填?
Delegate代理是一種回調(diào)機(jī)制拐云,是一對一的關(guān)系;而通知是基于觀察者模式的一對多的關(guān)系近她,消息會發(fā)送給所有注冊為事件觀察者的對象叉瘩;Delegate比Notification的執(zhí)行效率要高;

Block和Delegate一樣通常也是一對一的通知粘捎,使用場景相同薇缅,可以說Block是Delgate的另一種形式,但Block更加簡潔直接且輕便靈活攒磨,不需要像Delegate那樣需要定義協(xié)議很多方法泳桦,而且代理對象要實(shí)現(xiàn)協(xié)議方法,還需要建立對象間的代理關(guān)系才可以通信娩缰。在通信事件比較多的情況下灸撰,還是建議使用Delegate,Delegate的定義實(shí)現(xiàn)形式更加直觀清楚。

KVO就是cocoa框架實(shí)現(xiàn)的觀察者模式浮毯,一般同KVC搭配使用完疫,通過KVO可以監(jiān)測一個值的變化,比如View的高度變化债蓝。是一對多的關(guān)系壳鹤,一個值的變化會通知所有的觀察者。 NSNotification是通知饰迹,也是一對多的使用場景芳誓。在某些情況下,KVO和NSNotification是一樣的啊鸭,都是狀態(tài)變化之后告知對方锹淌。NSNotification的特點(diǎn),就是需要被觀察者先主動發(fā)出通知莉掂,然后觀察者注冊監(jiān)聽后再來進(jìn)行響應(yīng)葛圃,比KVO多了發(fā)送通知的一步,但是其優(yōu)點(diǎn)是監(jiān)聽不局限于屬性的變化憎妙,還可以對多種多樣的狀態(tài)變化進(jìn)行監(jiān)聽库正,監(jiān)聽范圍廣,使用也更靈活厘唾。

KVO一般的使用場景是數(shù)據(jù)褥符,需求是數(shù)據(jù)變化,比如股票價格變化抚垃,我們一般使用KVO(觀察者模式)喷楣。delegate一般的使用場景是行為,需求是需要別人幫我做一件事情鹤树,比如買賣股票铣焊,我們一般使用delegate。 Notification一般是進(jìn)行全局通知罕伯,比如利好消息一出曲伊,通知大家去買入。delegate是強(qiáng)關(guān)聯(lián)追他,就是委托和代理雙方互相知道坟募,你委托別人買股票你就需要知道經(jīng)紀(jì)人,經(jīng)紀(jì)人也不要知道自己的顧客邑狸。Notification是弱關(guān)聯(lián)懈糯,利好消息發(fā)出,你不需要知道是誰發(fā)的也可以做出相應(yīng)的反應(yīng)单雾,同理發(fā)消息的人也不需要知道接收的人也可以正常發(fā)出消息赚哗。 ***

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末她紫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子屿储,更是在濱河造成了極大的恐慌犁苏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扩所,死亡現(xiàn)場離奇詭異,居然都是意外死亡朴乖,警方通過查閱死者的電腦和手機(jī)祖屏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來买羞,“玉大人袁勺,你說我怎么就攤上這事⌒笃眨” “怎么了期丰?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吃挑。 經(jīng)常有香客問我钝荡,道長,這世上最難降的妖魔是什么舶衬? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任埠通,我火速辦了婚禮,結(jié)果婚禮上逛犹,老公的妹妹穿的比我還像新娘端辱。我一直安慰自己,他們只是感情好虽画,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布舞蔽。 她就那樣靜靜地躺著,像睡著了一般码撰。 火紅的嫁衣襯著肌膚如雪渗柿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天灸拍,我揣著相機(jī)與錄音做祝,去河邊找鬼。 笑死鸡岗,一個胖子當(dāng)著我的面吹牛混槐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轩性,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼声登,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悯嗓,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤件舵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后脯厨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铅祸,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年合武,在試婚紗的時候發(fā)現(xiàn)自己被綠了临梗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡稼跳,死狀恐怖盟庞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汤善,我是刑警寧澤什猖,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站红淡,受9級特大地震影響不狮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜在旱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一荤傲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颈渊,春花似錦遂黍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绍豁,卻和暖如春芯咧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背竹揍。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工敬飒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芬位。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓无拗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昧碉。 傳聞我的和親對象是個殘疾皇子英染,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評論 2 354

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