OC協(xié)議&代理? 本文為個人學習思考總結(jié)想罕,發(fā)表目的是為了獲得批評指正,交流想法。
/***************手動分割線根悼,第三版******************************************************************/
協(xié)議應定義在執(zhí)行類中批糟。
協(xié)議應該定義在執(zhí)行類中格了, 定義在委托類中,其他類想要委托委托類做相同的事情的時候徽鼎,需要聲明定義協(xié)議的委托類盛末,不合理。
協(xié)議定義在執(zhí)行類中否淤,并在執(zhí)行類的實習里悄但,實現(xiàn)協(xié)議規(guī)定的方法,任何委托類只要簽署該協(xié)議石抡,并持有執(zhí)行類的引用檐嚣,即可委托執(zhí)行類執(zhí)行協(xié)議里的方法,合理啰扛。
/***************手動分割線净嘀,第二版******************************************************************/
經(jīng)過一段時間的使用后,更新對協(xié)議侠讯、代理的理解挖藏。
協(xié)議二要素:執(zhí)行類、協(xié)議厢漩。
—— 協(xié)議
執(zhí)行類: 執(zhí)行協(xié)議方法的類膜眠, 標志,在其.h文件中溜嗜,且在@interface 的<> 中包含協(xié)議名宵膨。
協(xié)議:一系列方法簽名,由執(zhí)行類去實現(xiàn)炸宵。
協(xié)議可以寫在單獨的.h文件中辟躏,也可以寫在類的.h文件中。
單獨使用協(xié)議并沒有什么特別的約束作用土全,不會在執(zhí)行類沒有實現(xiàn)協(xié)議方法時報錯捎琐,最多拋出warning,但這就是協(xié)議的目的裹匙,告訴執(zhí)行類瑞凑,你還需要實現(xiàn)什么方法,你可以不實現(xiàn)協(xié)議規(guī)定的方法概页,但必須自己承擔后果籽御。
—— 代理
委托類:創(chuàng)建協(xié)議的類, 標志,在其.h 文件中技掏,有@protocol 的申明铃将;
代理,可以簡單理解為委托類要做點什么哑梳,但自己做不到劲阎。而執(zhí)行類能做到,于是涧衙,委托類就列舉了它想做的事情哪工,寫在協(xié)議里: @protocol 協(xié)議名。執(zhí)行類愿意去做這些事情弧哎,于是遵守協(xié)議:<協(xié)議名> 雁比。當委托類想要做協(xié)議中的事情的時候,它通知執(zhí)行類即可撤嫩。
協(xié)議:
#委托類.h
@protocol ProtocolName <NSObject>
- want2do1;
-want2do2;
@end
#執(zhí)行類.h
@interface 執(zhí)行類名 : NSObject <ProtocolName>
#執(zhí)行類.m
@implementation 執(zhí)行類名 {
//執(zhí)行類去做這些事偎捎。
- want2do1{
//具體實現(xiàn)
}
- want2do2{
//具體實現(xiàn)2
}
@end
委托類什么時候通知執(zhí)行類?怎么通知序攘?
首先來解決怎么通知:讓委托類持有執(zhí)行類的引用(持有執(zhí)行類的對象)
舉個例子茴她。app中頁面跳轉(zhuǎn):
UIViewController * delegateViewController =[ [DelegateViewController alloc]init];
delegateViewController.executeViewController = self; ? // 讓委托類獲取到執(zhí)行類的引用。
PS: 委托類中需要聲明一個變量來保存執(zhí)行類的引用:
#委托類.h
@interface 委托類名 : NSObject
...
@property id<ProtocolName> executeViewController;
@end
當委托類想做些協(xié)議中的事情的時候:通知執(zhí)行類執(zhí)行便可
[delegateViewController.executeViewController want2do1];
[delegateViewController.executeViewController want2do2];
說白了程奠,代理其實就是讓委托類拿到執(zhí)行類的引用丈牢,那便可以通過執(zhí)行類的引用,調(diào)用所有執(zhí)行類的方法瞄沙,當然己沛,這就有點不可控了,所有又使用協(xié)議來約束委托類通過執(zhí)行類的引用能做的事距境。@property id<ProtocolName>executeViewController; 這是委托類用來保存執(zhí)行類引用的變量申尼,從其聲明方式便能看出,委托類能通過這個引用做的事情垫桂,只能在協(xié)議Protocol 允許的范圍內(nèi)师幕,即協(xié)議ProtocolName 中列舉的方法。
/***************************************************************************************************************************************************/
——協(xié)議需要先理解
1.從三個要素理解協(xié)議
A:協(xié)議制定方(委托方):ClassA. ClassA負責定制協(xié)議
// ClassA.h
@interface ClassA
//classA自己的方法及屬性等
@protocol protocolA
/*
*協(xié)議內(nèi)容方法簽名列表
* eg: -(returnType) methodName : (paramType )paramName;
*
*/
@end
@end
B:協(xié)議(protocol):一系列方法簽名的列表诬滩,不能包含屬性霹粥;
//這是協(xié)議
@protocol protocolA
/*
*協(xié)議內(nèi)容方法簽名列表
* eg: -(returnType)protoclMthod1:(paramType ) paramName;
*/
@end
C:簽署協(xié)議方(代理):ClassB.ClassB與ClassA簽署A制定的某項協(xié)議(protocolA),去實現(xiàn)協(xié)議中聲明的方法。
//ClassB.h
@interface ClassB //在這里與ClassA簽署protocolA
//ClassB自身的方法及屬性等
@end
// ClassB.m
@implementation ClassB
// ClassB自身方法實現(xiàn)
//對protocolA的實現(xiàn)
-(returnType)protoclMthod1:(paramType ) paramName
{
//方法體
}
@end
以Java來講碱呼,由點像Interface蒙挑,目前我所理解的區(qū)別:1. protocol在類中定義,不用單獨地在文件中定義愚臀;2.對protocol的實現(xiàn)可以有選擇的實現(xiàn)。
2.代理
——在理解代理之前:
考慮這樣的場景:
假設需要在ClassA中,需要執(zhí)行ClassB的方法姑裂,卻無法直接獲取ClassB的對象(已經(jīng)創(chuàng)建了的對象)馋袜。
可能的解決方案:
讓ClassA的對象包含ClassB對象的引用——在ClassA中聲明一個變量來保存ClassB實例對象的引用,在使用ClassB方法前舶斧,將一個ClassB實例對象的引用賦值給這個變量(在ClassA的預編譯中添加對ClassB.h的引用欣鳖,以便ClassA能調(diào)用ClassB的方法)。
這個茴厉,我覺得就算一個簡單的代理——理解為引用似乎更合理泽台。
代理和協(xié)議的關系:
再次考慮剛才的場景:
需要在ClassA對象中,需要執(zhí)行ClassB的方法矾缓,卻無法直接獲取ClassB的對象(已經(jīng)創(chuàng)建了的對象)怀酷。
如果此時只允許ClassA的對象執(zhí)行ClassB中特定的方法,該如何實現(xiàn)呢嗜闻?
使用協(xié)議蜕依。
再次從三要素理解代理:
A:協(xié)議制定方(委托方):ClassA. ClassA負責定制協(xié)議
// ClassA.h
@interface ClassA
//classA自己的方法及屬性等
@protocol protocolA
/*
*協(xié)議內(nèi)容方法簽名列表
* eg: -(returnType) methodName : (paramType )paramName;
*/
@end
//聲明一個ID變量保存代理(引用)
//限制了ClassA對象通過delegate能操作的方法必須是protocolA里面簽名的方法。
@property(assign, nonatomic) iddelegate;
@end
以上琉雳,便是我對OC 協(xié)議和代理的粗淺理解样眠。歡迎批評指正。
以上內(nèi)容有參考