iOS Protocol 詳解
一、概述
Protocol(協議)的宣告看起來類似一個類的介面,不同的是Protocol沒有父類也不能定義例項變數。Protocol是一種特殊的程式設計結構,用於宣告專門被別的類實現的方法。因為OC是單繼承的,由於不支援多繼承,所以很多時候都是用Protocol和Category來代替實現多繼承。Protocol只能定義公用的一套介面,但不能提供具體的實現方法。也就是說,它只告訴你要做什麼,但具體怎麼做,它不關心。
Protocol的基本用途:
(1)可以用來宣告一大堆方法(不能宣告成員變數)
(2)只要某個類遵守了這個協議,就相當於擁有這個協議中的所有方法宣告
(3)只要父類遵守了某個協議,就相當於子類也遵守了
(4)和java中的介面很相似,但比介面功能更豐富
二、建立與遵守Protocol
1、建立Protocol
建立Protocol很簡單,如下圖:
比如我們填寫的檔名為MyProtocol,之後會生成一個MyPotocol.h檔案,檔案內容如下:
#import <Foundation/Foundation.h>
//注意下面的NSObject是基協議,而不是之前的基類
@protocol MyProtocol <NSObject>
//在此宣告方法
@end
之後我們就在其中宣告需要的方法,但要注意的是這裡只做宣告,不做實現。並且不能宣告變數
協議可用定義在單獨.h檔案中,也可用定義在某個類中:
(1) 如果這個協議只用在某個類中,應該把協議定義在該類中
(2) 如果這個協議用在很多類中,就應該定義在單獨檔案中
2、基協議
(1)NSObject是一個基類,是最根本最基本的類,任何其他類最終都要繼承它
(2)其實還有一個協議,名字也叫NSObject,它是一個基協議,最根本最基本的協議
(3)NSObject協議中聲明瞭很多最基本的方法,比如description、retain、release等
(4)建議每個新協議都要遵守NSObject協議
3、協議中方法宣告的關鍵字
(1) @required (預設)
要求實現,如果沒有實現,會發出警告,但不報錯
(2) @optional
不要求實現,不實現也不會有警告
例如:
@require
– (void)test;
@optional
– (void)test2;
4、遵守協議
首先要#import “協議檔名.h”或者@protocol 協議名稱,但是使用@protocol 協議名稱時只是告訴下面程式碼這是一個協議,但不知道協議裡面有什麼東西,一般只在用到協議內容的時候在#import”協議檔名.h”。在實際開發中常用@protocol 協議名稱。
(1) 類遵守協議
@interface 類名 : 父類名 <協議名稱1, 協議名稱2>
@end
(2) 協議遵守協議
@protocol 協議名稱 <其他協議名稱1, 其他協議名稱2>
@end
5、定義一個變數的時候,限制這個變數儲存的物件遵守某個協議
類名<協議名稱> *變數名;
NSObject<MyProtocol> *obj;
id<協議名稱> 變數名;
id<MyProtocol> obj2;
如果obj和obj2沒有遵守MyProtocol的協議,編譯器會警告。
6、@property中宣告的屬性也可用做一個遵守協議的限制
@property (nonatomic, strong) 類名<協議名稱> *屬性名;
@property (nonatomic, strong) Dog<MyProtocol> *dog;
@property (nonatomic, strong) id<協議名稱> 屬性名;
@property (nonatomic, strong) id<MyProtocol> dog2;
三、Protocol的一個簡單示例
例如:
我們新建一個Protocol,命名為HelloProtocol,然後就只會生成一個HelloProtocol.h檔案,注意肯定沒有.m檔案,協議只是用來宣告方法,並不是來實現的。
#import <Foundation/Foundation.h>
@protocol HelloProtocol <NSObject>
//預設就是required;
@required
- (void)requiredMethod;
@optional
- (void)optionalMethod;
@end
新建Person類,在Person.h中引入協議,如下:
#import <Foundation/Foundation.h>
#import "HelloProtocol.h"
@interface Person : NSObject<HelloProtocol>
@end
Person.m如下:
#import "Person.h"
@implementation Person
- (void)requiredMethod{
NSLog(@"requiredMethod——必須實現的方法");
}
- (void)optionalMethod{
NSLog(@"optionalMethod——選擇實現的方法");
}
@end
之後在main.m中建立Person的物件去呼叫這些方法:
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *jack = [[Person alloc] init];
[jack requiredMethod];
[jack optionalMethod];
}
return 0;
}
例子很簡單,這裡不做過多講解~
原創文章,轉載請註明: 轉載自李峰峰部落格