Objective-C協(xié)議

OC中協(xié)議是聲明方法的集合體,由類實(shí)現(xiàn)協(xié)議聲明的所有方法,稱之為類遵循(conform)方法。

協(xié)議的使用

協(xié)議的聲明

@protocol 協(xié)議名
聲明方法;
    ...
@end

協(xié)議的采用(adopt)

@interface 類名 : 超類名 <協(xié)議名>
{      
    聲明實(shí)例變量;
        ...
}
聲明方法;
    ...
@end
  • 類采用協(xié)議后,需要在實(shí)現(xiàn)文件中實(shí)現(xiàn)協(xié)議中聲明的方法。
  • 類可以采用多個(gè)協(xié)議,在尖括號(hào)中用逗號(hào)分隔。
  • 一個(gè)協(xié)議中不能聲明兩個(gè)選擇器相同而簽名不同的方法。

協(xié)議可以繼承協(xié)議

@protocol 協(xié)議名1 <協(xié)議名2>
聲明方法;
    ...
@end

指定協(xié)議的類型聲明

聲明某個(gè)對(duì)象適用于某個(gè)協(xié)議

id <協(xié)議名> obj;

可以將這個(gè)對(duì)象作為方法參數(shù),表明只要遵循了該協(xié)議的對(duì)象可以傳入。

協(xié)議的前置聲明

@protocol 協(xié)議名

協(xié)議適用性檢查

在運(yùn)行時(shí)可以動(dòng)態(tài)的檢查對(duì)象是否適用于某個(gè)協(xié)議。

//aProtocol參數(shù)指定的協(xié)議和類適用是,返回YES
+ (BOOL) conformsToProtocol: (Protocol *) aProtocol
//接收器類和參數(shù)aProtocol指定的協(xié)議適用時(shí),返回YES
- (BOOL) conformsToProtocol: (Protocol *) aProtocol

必選和可選

在Objective-C 2.0中規(guī)定了一項(xiàng)新規(guī)定,使用@optional和@required來標(biāo)注協(xié)議方法為可選的和必須實(shí)現(xiàn)的,默認(rèn)為@required,編譯器會(huì)警告沒有實(shí)現(xiàn)的@required方法,而不會(huì)警告@optional修飾的方法。

在采用協(xié)議的時(shí)候,需要?jiǎng)討B(tài)的檢查方法是否可用。使用responsToSelector:方法來檢查是否實(shí)現(xiàn)了某個(gè)方法

委托(Delegate)

委托模式是一種設(shè)計(jì)模式,在OC中,委托通過協(xié)議的方式實(shí)現(xiàn)。
委托可以用來監(jiān)聽、通知或者代理其他對(duì)象做一些事。這里通過租客通過中介租房的例子來介紹委托的使用方式。

租客想要租房子,但自己沒有時(shí)間,于是找了中介幫忙租,租客向中介提供了一個(gè)租房的協(xié)議,協(xié)議的目的是讓中介幫忙找房子,但租客不關(guān)心找房子具體的過程。

首先看類圖
委托模式租客和中介類圖.png

定義一個(gè)協(xié)議RentProtocol,聲明一個(gè)尋找房子的方法findingHouse
定義一個(gè)中介類Agent,實(shí)現(xiàn)RentProtocol協(xié)議
定義一個(gè)租客類Renter,聲明一個(gè)代理rentDelegate,這個(gè)代理必須遵守RentProtocol協(xié)議

協(xié)議部分代碼

@class Renter;
@protocol RentProtocol <NSObject>

- (BOOL)findingHouse:(Renter *)renter;//找房子的方法

@end

中介部分代碼

@interface Agent : NSObject <RentProtocol>

@property (strong, nonatomic) NSString *name;
- (instancetype)initWithName:(NSString *)name;

@end

@implementation Agent

- (instancetype)initWithName:(NSString *)name{
    _name = name;
    return self;
}

- (BOOL)findingHouse:(Renter *)renter{
    NSLog(@"%@的正在幫%@找房子", self.name, renter.name);
    return YES;
}

@end

租客部分代碼

@interface Renter : NSObject

@property (strong, nonatomic) NSString *name;//租客的名字
@property (strong, nonatomic) id <RentProtocol> rentDelegate;

- (instancetype)initWithName:(NSString *)name;
- (void)findHouseFromRenter;


@implementation Renter

- (instancetype)initWithName:(NSString *)name{
    _name = name;
    return self;
}

- (void)findHouseFromRenter{
    NSLog(@"%@準(zhǔn)備找中介租房子", self.name);
    BOOL checkProtocol = [self.rentDelegate conformsToProtocol:@protocol(RentProtocol)];//
//    BOOL checkProtocol = [self.rentDelegate respondsToSelector:@selector(findingHouse:)];
    if(!checkProtocol){
        NSLog(@"沒有找到代理,打包回家");
    } else{
        if([self.rentDelegate findingHouse:self]){
            NSLog(@"找到房子了!");
        }
    }
}

@end

上面的代碼使用了兩種方法判斷rentDelegate是否遵守了協(xié)議,conformsToProtocol判斷是否遵守該協(xié)議,而respondsToSelector判斷協(xié)議是否實(shí)現(xiàn)了findingHouse方法,通常使用后者,比如某些類遵守了協(xié)議但并沒有實(shí)現(xiàn)需要用到的方法。

main函數(shù)和打印結(jié)果

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Renter *renter = [[Renter alloc] initWithName:@"wilson"];
        Agent *agent = [[Agent alloc] initWithName:@"黑心中介"];
        renter.rentDelegate = agent;
        [renter findHouseFromRenter];
    }
    return 0;
}

2018-06-06 11:50:25.342768+0800 DelegateStudy[78708:10208881] wilson準(zhǔn)備找中介租房子
2018-06-06 11:50:25.343010+0800 DelegateStudy[78708:10208881] 黑心中介正在幫wilson找房子
2018-06-06 11:50:25.343027+0800 DelegateStudy[78708:10208881] 找到房子了!

在這個(gè)例子中,我們只定義了一個(gè)黑心中介的類來幫租客找房子,實(shí)際上只要遵守了這個(gè)協(xié)議的任何一個(gè)類,都可以作為租客的找房子代理者,例如租客的一個(gè)朋友也遵守了協(xié)議,實(shí)現(xiàn)了協(xié)議中的方法,同樣可以將該朋友的對(duì)象傳遞給租客的rentDelegate屬性。

協(xié)議使得開發(fā)更加靈活,面向協(xié)議(接口)編程也是一種提高架構(gòu)靈活性,降低耦合性的一種非常好的方式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容