1. 关于Protocol
在使用OC开发iOS程序的过程中经常会用到Protocol,定义一个Protocol的语法格式如下:
@protocol HumanProtocol <NSObject>
@required
- (void)name;
- (void)age;
//@optional
// ...
@end
它类似于java的接口interface,接口就是一堆方法的声明,没有实现。一般一个类可以遵循一个或多个协议,任何类只要遵循了协议就相当于拥有了这个协议中所有的方法声明。Protocol可以定义在一个类的头文件上部,并直接应用在该类中(如作为delegate功能使用时),Protocol也可以单独定义到一个类中,作为多个不同类来遵循并实现的interface。
#import <Foundation/Foundation.h>
@protocol HumanProtocol <NSObject>
@required
- (void)name;
- (void)age;
//@optional
// ...
@end
@interface Worker : NSObject
@property (nonatomic, copy) id<HumanProtocol> delegate;
@end
----------------------
#import "Peter.h"
#import "Worker.h"
@interface Peter : NSObject <HumanProtocol>
@end
@implementation Peter
// 实现定义的方法
- (void)name {
}
- (void)age {
}
@end
或
#import <Foundation/Foundation.h>
#import "HumanProtocol.h"
@interface Peter : NSObject <HumanProtocol>
@end
@implementation Peter
// 调用协议变量,或实现协议方法
@end
2. 使用示例
<NSObject>是一个基协议,每个新协议都需要遵循。@protocol是定义一个协议的注解,其中,@required表示这个方法必须被实现,@optional表示这个方法不一定要被实现。
简单应用场景:
一个人需要一个app,这个app必须有学习、买东西、分享等功能。
思路:
1、需要创建一个人和APP
2、需要创建一个Protocol来描述这些功能
3、人拥有的APP要实现这些功能
4、APP需要遵循这个Protocol且实现它
#import <Foundation/Foundation.h>
@protocol DoSomethingProtocol <NSObject>
- (void)buySomething;
- (void)studyEnglish;
- (void)shareInfo;
@end
----------------------------
#import <Foundation/Foundation.h>
#import "DoSomethingProtocol.h"
@class APP;
@interface Person : NSObject
//拥有的APP要实现Protocol的功能
@property (nonatomic,strong) APP<DoSomethingProtocol> *app;
@end
----------------------------
#import <Foundation/Foundation.h>
#import "DoSomethingProtocol.h"
@interface APP : NSObject<DoSomethingProtocol>
@end
#import "APP.h"
@implementation APP
- (void)buySomething {
NSLog(@"%s",__func__);
}
- (void)shareInfo {
NSLog(@"%s",__func__);
}
- (void)studyEnglish {
NSLog(@"%s",__func__);
}
@end
----------------------------
Person *p = [[Person alloc]init];
APP *app = [[APP alloc]init];
//赋值的时候就会判断app是否是符合协议的app,如果app没有遵循协议就会报警告
p.app = app;
//判断app是否有实现协议内容
if([p.app respondsToSelector:@selector(buySomething)]){
[p.app buySomething];
}
if ([p.app respondsToSelector:@selector(studyEnglish)]) {
[p.app studyEnglish];
}
if ([p.app respondsToSelector:@selector(shareInfo)]) {
[p.app shareInfo];
}
3. 需要注意的几个点
- 协议与继承的区别
继承之后默认就有实现,而protocol只要声明没有实现;相同类型的类可以使用继承,但是不同类型的类只能使用protocol;protocol可以用于存储方法声明,可以将多个类中共有的方法抽取出来,以后让这些类遵守协议即可
- Protocol 与 Category 的区别
Category给一个类可以扩充方法,既有申明也有实现,而Protocol只有声明,没有实现;Category可以声明方法,不能声明属性。而Protocol都可以,Protocol可以用@property形式声明属性,只不过在Protocol中声明的属性,只有对应的setter/getter方法声明,并没有生成对应的成员变量。
Protocol:
@protocol SportProtocol <NSObject>
@property (nonatomic,copy) NSString *sportType;
- (void)playFootball;
- (void)playBasketball;
- (void)run;
@end
实现类:
#import <Foundation/Foundation.h>
#import "SportProtocol.h"
@interface Person : NSObject<SportProtocol>
@end
#import "Person.h"
@implementation Person
@synthesize sportType=_sportType;
- (void)readSportType{
NSLog(@"%@",_sportType);
}
@end
上面方法中主要用到了@synthesize sportType=_sportType, 意思是说,sportType 属性为 _sportType 成员变量合成访问器方法。
Person *p =[[Person alloc]init];
p.sportType = @"sport";
[p readSportType];
父类遵守了某个类的Protocol,那么子类也会自动遵守这个Protocol
#import <Foundation/Foundation.h>
#import "SportProtocol.h"
@interface Person : NSObject<SportProtocol>
@end
----------------------
#import "Person.h"
@interface Student : Person
@end
----------------------
Student *stu = [[Student alloc]init];
[stu playBasketball];
一个类可以遵守多个Protocol
#import <Foundation/Foundation.h>
#import "SportProtocol.h"
#import "StudyProtocol.h"
@interface Person : NSObject<SportProtocol,StudyProtocol>
@end
Protocol又可以遵守其他Protocol,只要一个Protocol遵循了其他Protocol,那么这个Protocol就会自动包含其他Protocol的声明
#import <Foundation/Foundation.h>
#import "BaseProtocol.h"
@protocol StudyProtocol <BaseProtocol>
- (void)studyEnglish;
- (void)studyChinese;
@end
网友评论