协议的基础语法
定义
协议是方法的列表
协议只有一个.h文件
@protocal 协议名称
//方法声明列表
@end如何遵守协议< >:
#import “protocol.h”
//类遵守协议
@interface 类名: 父类名 <协议名称1,协议2>
@end
//协议遵守协议
@protocol 协议名称 <协议1 ,协议2 >
@end
协议方法声明的关键字:
@optional不要求实现
@required要求实现(默认)没有实现会发出警告
基协议:NSObject
只要一个类遵守了另外一个协议,就可以拥有另一个协议的所有方法声明。变量限制
- 定义一个变量时,限制这个变量保存的对象遵守某个协议:
类名<协议名称> * 变量名;
id<协议名称> 变量名;
如果没有遵守对应的协议,编译器会发出警告。
//要求p保存的对象必须是遵守protocol
NSObject *p = [ [NSObject alloc] init ]; //右边就会报错,没有遵守protocol协议
//id相当于NSObject *
id obj4 = [ [ Person alloc] init] ;
- @property中声明的属性也可以限制协议类型
@property (nonatomic, strong) 类名<协议名称> *属性名;
@property (nonatomic, strong) id<协议名称> 属性名;
性能优化:
类的声明.h文件中用到其他类和协议,优先使用@class, @protocol
实现文件.m中实际用到再用#import导入协议位置
当协议只用在某个类中,直接写在该类的.h头文件中;
当多个类/协议需要用到该协议,最好写一个专门的.h协议文件。
代理模式
协议可以单独文件定义,也可以定义在委托方的声明文件中(.h)
代理模式:a委托b干活,以需求方a为主体,找代理,协议写在a中,并建立委托关系a.delegate=b
- 例1
Boss要委托Worker去buyMac
// main.m
#import
#import "Boss.h"
#import "Worker.h"
int main(int argc, const charchar * argv[])
{
@autoreleasepool {
//用协议实现代理
//协议中定义了方法buyMac
//Boss中有个带协议的id型属性delegate,delegate就可以使用buyMac,但不用实现
Boss * mars = [[Boss alloc] init];
//老王遵从协议,并实现协议中声明的方法buyMac
Worker * laowang = [[Worker alloc] init];
//把Boss中delegate指向Worker变量
mars.delegate = laowang;
//相当于: id delegate = laowang;
[mars delegateBuyMac];
// 相当于: [delegate buyMac];
}
return 0;
}
// Boss.h
#import
//协议可以声明于委托方的头文件中
@protocol BossDelegate
//协议中规定 被委托的方法 买MAC
- (void)buyMac;
@end
@interface Boss : NSObject
//指向代理的指针,若引用(assign)
@property (assign) id delegate;
//委托代理替自己买MAC
-(void)delegateBuyMac;
@end
// Boss.m
#import "Boss.h"
@implementation Boss
//委托代理替自己买MAC
-(void)delegateBuyMac
{
//代理指针指向worker
[self.delegate buyMac];
//id指针调用协议上的方法
}
@end
// Worker.h
#import
#import "Boss.h"
@interface Worker : NSObject
//worker遵从协议,实现了协议上的方法 即买MAC的方法
//- (void)buyMac;
@end
// Worker.m
#import "Worker.h"
@implementation Worker
//采购MAC
- (void)buyMac
{
NSLog(@"Worker采购了一批MAC!");
}
@end
代理传值
- 正向传值:以委托方为主体,制定协议,代理方遵守协议。
- 逆向传值:以功能方(代理方)为主体,制定协议,客户(委托方)遵守协议。
- 正向传值例子(仍然是Boss和Worker)
//main.m
#import
#import "Worker.h"
#import "Boss.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Boss * mars = [[Boss alloc] init];
Worker * laowang = [[Worker alloc] init];
mars.delegate = laowang;
//传消息委托老王买Mac
[mars delegateBuyMac:@"帮我去买一个Mac吧"];
//询问老王结果
NSLog(@"%@",[mars askResult]);
}
return 0;
}
// Boss.h
#import
//协议可以声明于委托方的头文件中
@protocol BossDelegate
//协议中规定 被委托的方法 买MAC
- (void)buyMac;
@end
@interface Boss : NSObject
@property (assign) id delegate;
-(void)delegateBuyMac:(NSString*)message;
-(NSString*)askResult;
@end
// Boss.m
#import "Boss.h"
@implementation Boss
-(void)delegateBuyMac:message{
[self.delegate buyMac:message];
}
-(NSString*)askResult{
return [self.delegate returnMessage];
}
@end
// Worker.h
#import
#import "Boss.h"
@interface Worker : NSObject
//worker遵从协议,实现了协议上的方法 即买MAC的方法
//- (void)buyMac;
@end
// Worker.m
#import "Worker.h"
@implementation Worker
- (void)buyMac:message
{
NSLog(@"收到老板消息:%@",message);
NSLog(@"我去看一下MAC现在多少钱");
}
-(NSString*)returnMessage{
return @"boss!我买好了";
}
@end
运行结果如下图
- 逆向传值例子
下载处理:FirstViewController委托DownLoad下载东西
//main.m
#import
#import "FirstViewController.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
FirstViewController* firstVC = [[FirstViewController alloc]init];
[firstVC loadFirstView];
}
return 0;
}
//DownLoad.h
#import
//在提供功能的类中制定协议
@protocol DownLoadDelegate
-(void)finishLoading:(NSString*)message;
@end
@interface DownLoad : NSObject
@property(weak,nonatomic)id delegate;
-(void)downLoadWithUrl:(NSString*)url;
@end
//DownLoad.m
#import "DownLoad.h"
@implementation DownLoad
-(void)downLoadWithUrl:(NSString*)url{
NSLog(@"开始下载,地址:%@",url);
NSString* message=@"这里是下载得到的数据#¥%……&*";
[self.delegate finishLoading:message];
}
@end
// FirstViewController.h
#import
#import "DownLoad.h"
@interface FirstViewController : NSObject
-(void)loadFirstView;
@end
#import "FirstViewController.h"
#import "DownLoad.h"
@implementation FirstViewController
-(void)loadFirstView{
DownLoad* download = [[DownLoad alloc] init];
download.delegate=self;//构建委托关系
//向DownLoad传值!!!
[download downLoadWithUrl:@"www.baidu.com"];
}
//实现协议中的方法
-(void)finishLoading:(NSString *)message{
//获得DownLoad传的值!!!
NSLog(@"下载完成:数据内容如下:\n%@",message);
}
@end
回调和多继承
参考http://blog.csdn.net/macro_13/article/details/42005775