一、简单使用
1.基本用途
可以用来声明一大堆方法(不能声明成员变量);
只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明;只要父类遵守了某个协议,就相当于子类也遵守了。
2.格式
协议的编写:
@protocol 协议名称
// 方法声明列表
@end
某个类遵守协议:
@interface 类名 : 父类 <协议名称>
@end
某个协议遵守其他协议:
一个协议可以遵守其他多个协议,多个协议之间用逗号,隔开;一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明;
@protocol 协议名称 <其他协议名称, ……>
@end
协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流;
@required:这个方法必须要实现(若不实现,编译器会发出警告,不会报错)(默认);
@optional:这个方法不一定要实现(不要求实现,怎样写都不会有警告)。
@protocol MyProtocol2 <NSObject>
- (void)haha2;
@optional
- (void)haha3;
@end
4.定义一个变量的时候,限制这个变量保存的对象遵守某个协议
类名<协议名称> *变量名;
id<协议名称> 变量名;
NSObject<MyProtocol> *obj;
id<MyProtocol> obj2;
如果没有遵守对应的协议,编译器会警告
5.基协议
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它;
NSObject也是一个基协议,最根本最基本的协议;
NSObject协议中声明很多最基本的方法,比如description、retain、release等;
建议每个新的协议都要遵守NSObject协议。
#import <Foundation/Foundation.h>
#import "Myprotocol.h"
@protocol MyProtocol3 <Myprotocol>
- (void)hehe;
@end
6.@property中声明的属性也可用做一个遵守协议的限制
@property (nonatomic, strong) 类名<协议名称> *属性名;
@property (nonatomic, strong) id<协议名称> 属性名;
@property (nonatomic, strong) Dog<MyProtocol> *dog;
@property (nonatomic, strong) id<MyProtocol> dog2;
7.协议可用定义在单独.h文件中,也可用定义在某个类中
1> 如果这个协议只用在某个类中,应该把协议定义在该类中
2> 如果这个协议用在很多类中,就应该定义在单独文件中
8.分类可用定义在单独.h和.m文件中,也可用定义在原来类中
1> 一般情况下,都是定义在单独文件
2> 定义在原来类中的分类,只要求能看懂语法
二、@protocol和@class
1> 在.h声明文件中,用@protocol遵守某个协议,用@class包含某个对象;2> 在.m实现文件中,用#import真正包含协议对象的声明。
//#import "MyProtocol3.h"
//#import "MyProtocol2.h"
@class Hashiqi;
@protocol MyProtocol2;
@protocol MyProtocol3;
// 只要一个类遵守了某一份协议,就能拥有这份协议中的所有方法声明
@interface Person : NSObject <MyProtocol3, MyProtocol2>
@property (nonatomic, strong) id<MyProtocol2> obj;
@property (nonatomic, strong) Hashiqi *dog;
@end
三、代理模式实例
main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Agent.h"
#import "NextAgent.h"
int main()
{
Person *p2 = [[[Person alloc]init]autorelease];
NextAgent *a2 = [[[NextAgent alloc]init]autorelease];
p2.delegate = a2;
[p2 buyTicket];
//人
Person *p = [[Person alloc]init];
//代理
Agent *a = [[Agent alloc]init ];
//设置代理
p.delegate = a;
[p buyTicket];
[a release];
[p release];
return 0;
}
person.h
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface Person : NSObject
- (void)buyTicket;
//拥有一个代理属性
//代理的类名随便,必须遵守TicketDelegate协议
@property (nonatomic,retain) id<TicketDelegate> delegate;
@end
person.m
#import "Person.h"
@implementation Person
- (void)buyTicket;
{
//叫代理去帮自己买票(询问一下票价、剩余张数)
double price = [_delegate ticketPrice];
int number = [_delegate leftTicketNumber];
NSLog(@"通过代理的帮助,票价=%f 还剩%d张票",price,number);
}
- (void)dealloc
{
[_delegate release];
[super dealloc];
}
@end
Agent.h
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface Agent : NSObject <TicketDelegate>
//返回票价
- (double)ticketPrice;
//还剩多少张票
- (int)leftTicketNumber;
@end
Agent.m
#import "Agent.h"
@implementation Agent
//剩余的票数
- (int)leftTicketNumber
{
//...亲自跑电影院\打电话
return 1;
}
//票价
- (double)ticketPrice;
{
return 1000;
}
@end
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@interface NextAgent : NSObject <TicketDelegate>
@end
NextAgent.m
#import "NextAgent.h"
@implementation NextAgent
- (int)leftTicketNumber
{
//...亲自跑电影院\打电话
return 200;
}
//票价
- (double)ticketPrice;
{
return 100;
}
@end
TicketDelegat.h
#import <Foundation/Foundation.h>
@protocol TicketDelegate <NSObject>
//返回票价
- (double)ticketPrice;
//还剩多少张票
- (int)leftTicketNumber;
@end