代理,又稱委托代理(delegate),是iOS中常用的設計一種模式。顧名思義,它是把某個對象要做的事情委托給別的對象去做。那麼別的對象就是這個對象的代理,代替它來打理要做的事。反映到程序中, 首先要明確一個對象的委托方是哪個對象,委托所做的內容是什麼。在iOS程序設計中,委托通過一種@protocol的方式實現,所以又稱為協議。在iOS的SDK裡面,UITableView、UITextField等都有用到這種設計模式。
協議,是多個類共享的一個方法列表,在協議中所列出的方法沒有響應的實現,由其它類來實現。委托是指給一個對象提供機會對另一對象中的變化做出反應或者相應另一個對象的行為。其基本思想是協同解決問題。
從方法的定義我們不難看出委托模式能夠起到兩方面的作用:
第一:代理協助對象主體完成某項操作,將需要定制化的操作通過代理來自定義實現,達到和子類化對象主體同樣的作用。
第二:事件監聽,代理對象監聽對象主體的某些重要事件,對事件做出具體響應或廣播事件交給需要作出響應的對象。
個人理解采用委托模式的好處在於:
1、避免子類化帶來的過多的子類以及子類與父類的耦合
2、通過委托傳遞消息機制實現分層解耦
在程序中:一般情況下
1.委托需要做的工作有:
1.1定義協議與方法
1.2聲明委托變量
1.3設置代理
1.4通過委托變量調用委托方法
2.代理需要做的工作有:
2.1遵循協議
2.2實現委托方法
比如,學生想要買一本專業書,書店沒有這本書,自己又不直接去出版社,於是,學生就委托書店,幫忙買書,書店就是學生的代理。
學生 Student.h裡面:
#import <Foundation/Foundation.h> //定義協議與方法 @protocol StudentBuyBookDelegate<NSObject> -(void)buyBook:(NSString *)name price:(int)p; @end @interface Student : NSObject //聲明委托變量 @property(nonatomic,retain)id<StudentBuyBookDelegate> stu_delegate; -(void)wantBuy; @end
學生Student.m裡面:
#import "Student.h" @implementation Student -(void)wantBuy { NSLog(@"學生:我想買IOS開發的書"); //通過委托變量調用委托方法 [self.stu_delegate buyBook:@"IOS開發" price:50]; } @end
書店BookShop.h
#import <Foundation/Foundation.h> #import "Student.h" //書店遵守StudentBuyBookDelegate的委托協議 @interface BookShop : NSObject<StudentBuyBookDelegate> @end
書店BookShop.m
#import "BookShop.h" @implementation BookShop //書店實現協議的方法 -(void)buyBook:(NSString *)name price:(int)p { NSLog(@"我可以以%i元的價格把%@賣個你",p,name); } @end
在ViewController.m裡面
Student *student =[[Student alloc]init]; BookShop *bookshop = [[BookShop alloc]init]; //學生設置代理,委托書店買書 student.stu_delegate=bookshop; //判斷書店是否實現了協議,避免未實現帶來的崩潰 if ([bookshop respondsToSelector:@selector(buyBook:price:)]) { [student wantBuy]; }
結果如圖:
總結:協議是一個方法簽名的列表,在其中可以定義若干個方法。根據配置,遵守該協議的類會去實現這個協議中規定的若干個方法。代理是一個概念,很難用一個名詞去定義(如我們可以說協議其實就是一個方法列表)。它更像是一種關系,我要做某一個事情,但我自己不想去做這件事,我委托其他人幫我去做這件事。這個時候,這位其他人就是我的代理。
本文側重於概念的理解,通過學生書店購書的例子,解釋了代理協議的概念。下文《iOS 用代理實現界面反向傳值》將側重於代理協議在iOS 程序設計的應用,比如界面反向傳值等等。