iOS開發總結——協議代理的認識

來源:互聯網
上載者:User

標籤:

1.前言

        自今年5月底正式轉iOS之後,天天get新技能,很多技能在腦子裡迴旋不吐不快,所以,寫點東西整理一下。先從協議代理開始。

2.協議方法的聲明
@protocol EventMenuBarDelegate <NSObject>- (void)delegateShouldDoWhenMenuButtonTapped:(UIButton *)button;@end

 

以上代碼意思是,利用@protocol 指令聲明協議名EventMenuBarDelegate,並遵從NSObject協議,在協議中聲明了一個方法

- (void)delegateShouldDoWhenMenuButtonTapped:(UIButton *)button,由於沒有用@option 指令聲明,所以服從該EventMenuBarDelegate的對象必須實現delegateShouldDoWhenMenuButtonTapped: 這個方法。

 

3.協議代理的認識

        協議中聲明的方法,其實就是C++等物件導向的程式設計語言的抽象方法,不需要具體實現過程,但是必須要聲明方法介面,以用於繼承該類的子類進行適配,這就是設計模式中的適配器模式。在Objective-C中,子類通過遵從協議和繼承超類以達到C++的多繼承的效果。我認為這樣的好處就是,多態。

4.情景類比與代碼實現

        委託代理其實就是某個對象需要完成某個方法所找的另外一個對象。比如,我是個懶人,我不喜歡洗衣服,我找洗衣助理幫我洗,此時,助理就是我洗衣服的委託代理,並且必須遵從洗衣協議並實現洗衣服的過程。在助理洗完之後,我再作為洗衣助理的委託代理表示感謝,向助理說謝謝並付錢。(有點繞,需要腦洞大開)如果用程式實現就可以像下面一樣寫。其實,這個情景中,代碼類比了兩個委託代理,一個是洗衣服的協議代理,另外一個是整個商務邏輯的協議代理。

1)洗衣服的協議方法

#import <Foundation/Foundation.h>#import "APPBLLDelegate.h" @protocol WashClothes <NSObject>- (void)washClothes:(int)num complete:(id<APPBLLDelegate>)delegate;@end

 

代碼聲明了洗衣服的協議,遵從該協議的所有對象必須完成一件事根據傳入的衣服數量洗衣服,洗完之後代理我(代理)再做出響應的處理。

2)商務邏輯協議

@protocol APPBLLDelegate <NSObject>- (void)didWashClothesSuccess:(BOOL)finished leftNum:(int)left;- (void)didWashClotheFailed:(NSString *)errorMsg;@end

商務邏輯的協議中,聲明了兩個方法,一個是洗衣成功後我需要做的,另一個是洗衣未成功我需要做的。其實,這裡完全可以抽象成任何事件的協議方法,換個名字就成。比如,一次網路請求響應,一次資料庫的讀庫寫庫。

而作為該商務邏輯的我(代理)而言,當洗衣助理把我當代理參數傳入的時候,並不確定我的類型,僅作為一個id類型的對象指標傳入,但是我必須遵循APPBLLDelegate協議,即

(id<APPBLLDelegate>)delegate

3)我(使用者)的類代碼實現

標頭檔

#import <Foundation/Foundation.h>#import "WashClothes.h"#import "APPBLLDelegate.h"@interface User : NSObject <APPBLLDelegate>@property int clothesNum;@property (weak, nonatomic) id<WashClothes> delegate;- (void)askAssistantForWashingClothes;@end

 

我洗衣服的代理是助理,助理的類不一定是什麼類,我不確定,所以用id類型來指代其類型(當然,如果確定的話就指定這個類名就好),但是助理必須遵循洗衣協議,即,

id<WashClothes> delegate

而我作為整個商務邏輯的代理,我也必須遵循商務邏輯的協議(腦洞再大點)。即,

 User : NSObject <APPBLLDelegate>

實現檔案

#import "User.h"@implementation User- (void)askAssistantForWashingClothes {    [self.delegate washClothes:self.clothesNum complete:self];}- (void)didWashClothesSuccess:(BOOL)finished leftNum:(int)left {    if (finished) {        NSLog(@"助理已洗完衣服,很感謝,支付洗衣費用");    } else {        NSLog(@"助理未能洗完衣服,剩餘%d件", left);    }}- (void)didWashClotheFailed:(NSString *)errorMsg {    if (errorMsg != nil) {        NSLog(@"報錯:%@", errorMsg);    }}@end

 

我不洗衣服,我請求助理洗衣服,那麼助理必須遵循洗衣協議,並且實現其具體過程,但我不需要實現,我的工作僅是向代理髮送洗衣訊息。當我的助理洗完衣服之後,我作為商務邏輯的代理,我必須做出反應,比如我要說謝謝給錢,或者沒洗完不給錢,再或者出現問題我要報錯。

這裡,商務邏輯可以抽象為一個網路請求,比如,網路狀況良好,我請求成功,正確傳參,正確返回。或者,網路狀況良好,錯誤傳參,錯誤返回。再或者,網路狀況渣渣,就報錯吧。。

4)洗衣助理要做的

標頭檔

#import <Foundation/Foundation.h>#import "WashClothes.h"@interface Assistant : NSObject <WashClothes>@property int totalNum;- (instancetype)init;@end

洗衣助理必須遵循洗衣協議,即,

Assistant : NSObject <WashClothes>

實現洗衣方法,即,

- (void)washClothes:(int)num complete:(id<APPBLLDelegate>)delegate;

實現檔案

#import "Assistant.h"@implementation Assistant- (instancetype)init {    self = [super init];    if (self) {        self.totalNum = 10;    }    return self;}- (void)washClothes:(int)num complete:(id<APPBLLDelegate>)delegate {    int left = self.totalNum - num;    if (left > 0) {        [delegate didWashClothesSuccess:YES leftNum:left];    } else {        [delegate didWashClothesSuccess:NO leftNum:abs(left)];        [delegate didWashClotheFailed:@"未能洗完衣服!"];    }}@end

        洗衣助理在初始化對象時,預設洗衣服最大數目是10件,並實現洗衣服的具體過程,洗完衣服之後給我(商務邏輯的代理)發送訊息。也就是說,洗衣助理只需要洗衣服,不需要管洗完衣服做什麼,剩下的將結果回傳給我,讓我來進行訊息反饋。

5)程式單一入口

#import <Foundation/Foundation.h>#import "User.h"#import "Assistant.h"int main(int argc, const char * argv[]) {    @autoreleasepool {                User *user = [[User alloc] init];        user.clothesNum = 20;                Assistant *assistance = [[Assistant alloc] init];        user.delegate = assistance;                [user askAssistantForWashingClothes];                  }    return 0;}

主程式建立了執行個體我,設定我的洗衣數量20,建立助理執行個體,設定我的洗衣委託代理為助理,最後向助理髮送訊息,助理執行洗衣服這個方法。

6)運行結果

2015-07-23 11:34:07.869 NYDelegateTest[1313:68830] 助理未能洗完衣服,剩餘10

2015-07-23 11:34:07.870 NYDelegateTest[1313:68830] 報錯:未能洗完衣服!

5.小結

1)Objective-C的協議可以實現適配器模式,通過繼承和遵循協議,達到C++的多繼承效果。通過該機制可以實現多子類的適配,使不同子類擁有各自獨特的方法,匹配自身需求。

2)運用協議代理代碼實現時,必須要設定執行個體的代理,比如,

user.delegate = assistance;

這一句必不可少,否則,代理是nil,發送訊息就失效,方法不能執行,不會有任何輸出。

3)這個類比情景中,代碼實現了兩個協議代理。

一個是,我找助理作為我的洗衣代理。

另一個是,助理洗完衣服後,將處理結果回傳給我(商務邏輯代理)。

4)在自學之初,我始終搞不清楚,table view的data source和delegate。現在才明白,其實兩者都是協議代理,只不過名字不同罷了。data source的方法主要針對table view的一些UI資料來源載入顯示。而delegate更多的是對table view的一些操作作出響應(但是也有什麼height之類的協議方法,我也是醉了,強迫症傷不起)。總之,如果單獨建立table view 而不是用table view controller,data source和delegate都必須設定,且實現其協議方法。

5)文章如有理解錯誤,請留言交流,我會及時訂正,感謝~

6)來上海之後,我兩個月內成長了很多,學到很多,很感恩。我希望把我所學到明白的東西熟練應用,並能深入理解其原理,所以要學的很多很多。但是現在淡定多了。終生學習,快樂學習。謝謝協助我的所有人 @不知霜舞哀傷udspj @tinyfool ,我的美女leader @七了個六 。加油加油我可以做的更好!

 

iOS開發總結——協議代理的認識

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.