protocol概念及基本使用
1、protocol的基本概念
協議:一些方法的聲明,一般寫到一個.h的頭文件中,供其他的類或者協議去遵守。
在OC中,接口是有一個叫做協議的protocol來實現的。它與java不同的是,它可以聲明一些必須實現的方法和選擇實現的方法,有選擇性的。
2、protocol的使用流程
協議的使用流程:定義協議—》再類中採用指定的協議—》實現協議中對應的方法(選擇性的)
1)定義協議
@protocol 協議名稱 <NSObject>
//默認遵守NSObject協議
//方法聲明列表
@end
2)採用協議
1、類遵守協議
創建類的時候遵守某個或者幾個協議
@interface 類名 :父類<協議名稱>
@end
@interface 類名 :父類<協議名稱1,協議名稱2>
@end
2、協議遵守協議
某個協議也遵守某個或者某些協議,一個協議可以遵守其他多個協議,多個協議之間用逗號','隔開
@protocol 協議名稱<其他協議名稱>
@end
3)實現對應的方法(必須要實現的)
結論:當我們遵守了某個協議後,就相當於這個類有了協議中所有的方法聲明
protocol的其他用法
1、protocol的使用注意
1)protocol:就一個用途,用來聲明一大堆的方法(不能聲明成員變量),不能寫實現
2)只要某個類遵守了這個協議,就擁有了這個協議的所有方法聲明
3)只要父類遵守某個協議,那麼子類也遵守
4)protocol聲明的方法可以讓任何類去實現,protocol就是協議
5)OC不能繼承多個類(單繼承),但是可以遵守多個協議。繼承(:),遵守協議(<>)
6)基協議:<NSObject>是基協議,是最根本最基本的協議,其中聲明瞭很多最基本的方法
7)協議可以遵守協議,一個協議遵守了另一個協議,就可以擁有另一個協議中的方法聲明
2、protocol基協議介紹
NSObject是一個積累,最根本最基本的類,任何其他類最終都要繼承它。它還有名字也叫NSObject的協議
,它是一個基協議,最根本最基本的協議。
建議每個新的協議都要遵守NSObject協議。
protocol中@required和@optional
@required和@optional是協議方法聲明中的兩個關鍵字
它們主要用於控制方法是否要實現(默認是@required),在大多數情況下,用途在於程序員之間的交流
//必須要實現,不實現編譯器報錯
//不加關鍵字,默認是要實現的
@required
-(void)run;
-(void)eat;
//可以實現,也可以不實現
@optional
-(void)fight;
protocol類型限制
1、protocol類型限制
1)給id類型增加限制
Girl
*mm = [Girl
new];
//由於id類型可以接受任何類型的對象,要增加類型限制
//id<協議名稱>,限制obj,只能賦值遵守了household協議的對象
id<houseHoldProtocol> obj = mm;
2)給具體對象增加限制
1、
Girl<houseHoldProtocol> *obj = mm;//在遵守協議的前提下,對象還必須是合理地
2、
@property
(nonatomic,
strong) Dog<suanShuProtocol> *dog;//人擁有會算數的狗,任意的狗就不可以
2、id和instancetype的區別
1)instancetype只能作爲函數或者方法的返回值
2)id能作爲方法或者函數的返回值、參數類型,也能用來定義變量
3)instancetype對比id的好處:能夠精確地限制返回值的具體類型
protocol代理設計模式
代理模式:嬰兒和保姆之間有個協議,保姆遵守該協議,於是保姆就需要實現該協議中的條款,從而成爲代理人。
錯誤:linker command failed with exit code 1 (use -v to see invocation)
1)重複包含頭文件
2)第三方庫
1、protocol代理設計模式概念
MVC模式:m-model(模型) v-view(視圖) c-controller(控制器)
代理模式:傳入的對象,代替當前類完成了某個功能。
利用協議實現代理模式的主要思路:
1)定義一個協議,裏面聲明代理類需要實現的方法列表
2)創建一個代理類(比如BaoMu),遵守上面的協議
3)在需要代理的類(Baby)中,定義一個對象,類型爲id,且遵守代理協議的成員變量
4)在Baby類中調用成員變量_delegate(代理對象)的方法,調用代理類的方法
5)main.m或其他使用Baby類的文件中,爲成員變量賦值
2、protocol代理模式的應用場合
1)當對象A發生了一些行爲,想告訴對象B(讓對象B稱爲對象A的代理對象)—》通知場合
2)對象B想監聽對象A的一些行爲(讓對象B稱爲對象A的代理對象)—》監聽器場合
3)當對象A無法處理某些行爲的時候,想讓對象B幫忙處理(讓對象B稱爲對象A的代理對象)—》自己不想或不能處理
思路實現例子:
1)協議:
#import
<Foundation/Foundation.h>
@class
Baby;
@protocol
lookBabyProtocol <NSObject>
//喂嬰兒喫飯
-(void)feedBabyEat:(Baby
*)baby;
//哄嬰兒睡覺
-(void)HongBabySleep:(Baby
*)baby;
@end
2)代理類:
#import
<Foundation/Foundation.h>
//保姆想成爲嬰兒代理人,必須遵守協議
#import
"lookBabyProtocol.h"
@interface
BaoMu : NSObject<lookBabyProtocol>
@end
#import
"BaoMu.h"
#import "Baby.h"
@implementation
BaoMu
//喂嬰兒喫飯
-(void)feedBabyEat:(Baby
*)baby {
baby.blood
+= 10;
NSLog(@"保姆正在喂嬰兒喫東西!體力值現在爲%.2f",
baby.blood);
}
//哄嬰兒睡覺
-(void)HongBabySleep:(Baby
*)baby {
baby.sleep
+= 20;
NSLog(@"保姆正在哄嬰兒睡覺!睡眠值現在爲%.2f",
baby.sleep);
}
@end
3)需要代理的類:
#import
<Foundation/Foundation.h>
@class
BaoMu;
#import
"lookBabyProtocol.h"
@interface
Baby : NSObject
//保姆、體力值、睡眠
@property
(nonatomic,
strong)
BaoMu<lookBabyProtocol> *bm;//此處代理對象一般爲_delegate
@property
(nonatomic,
assign)
float
blood;
@property
(nonatomic,
assign)
float
sleep;
//喫、睡
-(void)wantEat;
-(void)wantSleep;
@end
#import
"Baby.h"
#import "BaoMu.h"
@implementation
Baby
-(void)wantEat {
NSLog(@"嬰兒在哭...");
//保姆要喂他喫
[self.bm
feedBabyEat:self];
}
-(void)wantSleep {
NSLog(@"嬰兒在哭...");
//保姆要哄她睡
[self.bm
HongBabySleep:self];
}
@end
4)賦值:
#import
<Foundation/Foundation.h>
#import "BaoMu.h"
#import "Baby.h"
int
main(int
argc, const
char * argv[]) {
@autoreleasepool
{
BaoMu
*baomu = [BaoMu
new];
Baby
*baby = [Baby
new];
baby.bm
= baomu;
baby.blood
= 10;
baby.sleep
= 10;
[baby wantEat];
[baby wantSleep];
}
return
0;
}
引入協議
@protocol 協議名;//類似@class的用法
1、要遵守這個協議的類,用@protocol 告訴編譯器這時一個協議
2、在.m文件中,導入協議頭文件
3、在main函數中,也要導入協議頭文件