一、protocol(協議)相似java中的接口,定義了一些類須要公用到的方法,只要遵照這個協議,就能夠擁有這些方法並能夠去實現它們,這樣能夠避免許多重複的代碼。
java
好比,一個Teacher(老師)類,一個Student(學生)類
ui
老師有goToClassroom(去教室),goToToilet(去廁所),goToOffice(去辦公室)等方法,學生也有
atom
這樣Teacher類和Student類都須要聲明重複的代碼
spa
Teacher.hssr
#import <Foundation/Foundation.h> @interface Teacher : NSObject - (void)goToClassroom; - (void)goToToilet; - (void)goToOffice; @end
Student.h代理
#import <Foundation/Foundation.h> @interface Student : NSObject - (void)goToClassroom; - (void)goToToilet; - (void)goToOffice; @end
實現方法我就不實現了,若是這時有個協議來制定這些方法,讓Teacher和Student都去遵照的話,就不須要重複這麼多代碼
code
SchoolDaily.horm
#import <Foundation/Foundation.h> @protocol SchoolDaily <NSObject> - (void)goToClassroom; - (void)goToToilet; - (void)goToOffice; @end
這時Teacher和Student只須要遵照SchoolDaily協議並實現協議裏的方法便可擁有這些方法對象
Teacher.h接口
#import <Foundation/Foundation.h> #import "SchoolDaily.h" @interface Teacher : NSObject <SchoolDaily> @end
Student.h
#import <Foundation/Foundation.h> #import "SchoolDaily.h" @interface Student : NSObject <SchoolDaily> @end
二、@required表明協議裏的方法必須實現,不然編譯器會警告,不寫默認是@required,@optional表明協議裏的方法是選擇實現
好比,goToOffice方法Student能夠選擇不實現
SchoolDaily.h
#import <Foundation/Foundation.h> @protocol SchoolDaily <NSObject> @required - (void)goToClassroom; - (void)goToToilet; @optional - (void)goToOffice; @end
三、協議能夠與代理模式相結合
代理模式:委託(delegate),顧名思義就是委託別人辦事,就是當一件事情發生後,本身不處理,讓被人來處理。
a、在不使用delegate時,Teacher在修改做業前須要Student幫他收做業,則須要擁有學生這個變量
b、學生擁有pickupHomeWork(收做業)這個方法
c、老師擁有checkHemoWork(改做業)這個方法
Student.h
#import <Foundation/Foundation.h> @interface Student : NSObject - (void)pickupHomework; @end
Student.m
#import "Student.h" @implementation Student - (void)pickupHomework { NSLog(@"學生收做業"); } @end
Teacher.h
#import <Foundation/Foundation.h> #import "Student.h" @interface Teacher : NSObject @property(nonatomic, strong) Student *stu; - (void)checkHomework; @end
Teacher.m
#import "Teacher.h" @implementation Teacher - (void)checkHomework { // 叫學生幫他收做業 [_stu pickupHomework]; // 本身修改做業 NSLog(@"老師修改做業"); } @end
d、可是,Teacher和Student的耦合性太強,若是有一天這個Student畢業了,換成了Student2來收做業,Teacher類裏要修改的代碼也很多
f、使用代理的話,Teacher裏就不須要修改代碼,只須要把Student換成Student2便可
g、因而老師寫了一份協議,只有遵照此協議的才能當他的課表明,才能夠去收同窗的做業
Homework.h
#import <Foundation/Foundation.h> @protocol Homework <NSObject> - (void)pickupHomework; @end
Teacher.h
#import <Foundation/Foundation.h> #import "Homework.h" @interface Teacher : NSObject @property (nonatomic, strong) id<Homework> delegate; - (void)checkHomework; @end
Teacher.m
#import "Teacher.h" @implementation Teacher - (void)checkHomework { // 叫學生幫他收做業 [_delegate pickupHomework]; // 本身修改做業 NSLog(@"老師修改做業"); } @end
接下來不管是Student仍是Student2還有其餘阿貓阿狗類,只要遵照老師的協議就能夠有權利去收做業了
Student.h
#import <Foundation/Foundation.h> #import "Homework.h" @interface Student : NSObject <Homework> @end
Student.m
#import "Student.h" @implementation Student - (void)pickupHomework { NSLog(@"學生收做業"); } @end
須要注意如下幾點:
1.id能夠表示任何一個ObjC對象類型,類型後面的」<協議名>「用於約束做爲這個屬性的對象必須實現該協議(注意:使用id定義的對象類型不須要加「*」)
2.在.h文件中若是使用了另外一個文件的類或協議咱們能夠經過@class或者@protocol進行聲明,而沒必要導入這個文件,這樣能夠提升編譯效率
3.在編寫代碼中,協議代理文件一般以Delegate結尾,由於Delegate是代理的英文,這樣作方便之後的管理和交接
4.代理協議文件中必定要包含基協議<NSObject>