这次我为大家介绍装饰设计模式中的delegate。
一. 什么是delegate
从委托方法的实现来看,委托方法的实现是在另外一个类中完成,即委托类的内部暴露了,与我们一般坚持的隐藏实现原则相违背。
从委托类的定义可以看出,委托与协议有一定的相似性。都采用protocol关键字来声明
,并且其中的方法都有optional和required,都需要对required方法和调用的optional方法进行实现。而不同的是在委托对象所在的类中需要定义一个delegate对象,并且为id类型。
二. delegate的用途
但是delegate与protocol没有关系。Delegate本身应该称为一种设计模式,是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成,而实际做事的类为delegate。而protocol是一种语法,它的主要目标是提供接口给遵守协议的类使用,而这种方式提供了一个很方便的、实现delegate模式的机会。
为什么需要协议?
苹果的官方文档指出三个原因:
To declare methods that others are expected to implement
To declare the interface to an object while concealing its class
To capture similarities among classes that are not hierarchically related
通常,一个delegate的使用过程,需要经过五步:
1. 创建一个 delegate;
2. 委托者声明一个delegate;
3. 委托者调用delegate内的方法(method);
4. 被委托者设置delegate,以便被委托者调用;
5. 被委托者实现Delegate 所定义的方法。
给出栗子,程序猿学习路上的拙劣使用:
这是鄙人在网络请求时返回数据使用的delegate, 目的是为了在另一个类中完成实现,得到请求的数据;
@protocol URLProtocol
@required
- (void)returnarray:(NSDictionary *)data;
@end
@property (nonatomic, retain)iddelegate;
接着:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"数据加载完毕");
//处理服务器返回的所有数据
NSDictionary *dict =[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves
error:nil];
[self.delegate returnarray:dict];
使得delegate得到请求的数据;
之后就可以在其他类中使用了。
在viewcontroller.m中
@interface ViewController ()
@end
- (void)viewDidLoad {
MyRequest *request =[[MyRequest alloc] init];
request.delegate = self;
request.citystring =readArray[_index];
[request startAsynrc];
}
- (void) returnarray:(NSDictionary *)data{
int i=0;
// NSLog(@"%@",data);
NSString *Update = [data objectForKey:@"date"];// 2015-10-17
NSLog(@"%@",Update);
}
得到从网络请求的数据,并在controller中成功调用。
给出我的网络请求部分代码:
//
// MyRequest.h
// Getnet
//
// Created by Macbook on 15/10/15.
// Copyright © 2015年 Macbook. All rights reserved.
//
#import
#import "ThirdViewController.h"
@protocol URLProtocol
@required
- (void)returnarray:(NSDictionary *)data;
@end
@interface MyRequest : NSMutableURLRequest
@property (nonatomic,retain) NSMutableData *responseData;
@property (nonatomic,retain) NSURLConnection *connection;
@property (nonatomic, retain)iddelegate;
@property (nonatomic,retain) NSDictionary *data;
@property (nonatomic,retain) NSString *citystring;
//@property (nonatomic,retain) NSMutableArray
//开始异步请求
- (void)startAsynrc;
//取消异步请求
- (void)cancel;
返回数据
//- (void)returnarray:(NSDictionary *)data;
@end
//
// MyRequest.m
// Getnet
//
// Created by Macbook on 15/10/15.
// Copyright © 2015年 Macbook. All rights reserved.
//
#import "MyRequest.h"
#import "ViewController.h"
#import "AppDelegate.h"
@implementation MyRequest
#pragma mark- NSURLConnectionDataDelegate代理方法
//开始异步请求
- (void)startAsynrc{
//设置请求路径
// NSString *urlStl =[NSString stringWithFormat:@"http://aqicn.org/publishingdata/json"];
NSString *string =_citystring;
NSString *urlStl =[NSString stringWithFormat:@"http://api.map.baidu.com/telematics/v3/weather?location=%@&output=json&ak=Gi27P5bmIinr86htrjU4ESnY",string];
urlStl = [urlStl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url =[NSURL URLWithString:urlStl];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
//设置方法
[request setHTTPMethod:@"GET"];
[request setURL:url];
//设置超时时间
[request setTimeoutInterval:60];
self.responseData =[NSMutableData data];
self.connection =[NSURLConnection connectionWithRequest:request delegate:self];
}
//取消异步请求
- (void)cancel{
[self.connection cancel];
}
#pragma mark - NSURLConnection delegate
//当接受到服务器的响应(联通了服务器时会调用)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(@"接受到服务器的响应");
self.responseData = [NSMutableData data];
}
//当接受到服务器的数据时会调用 (可能多次调用 每次传递部分数据)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"接受到服务器数据");
//拼接数据
[self.responseData appendData:data];
NSLog(@"%ld---%@--",self.responseData.length,[NSThread currentThread]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"数据加载完毕");
//处理服务器返回的所有数据
NSDictionary *dict =[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves
error:nil];
[self.delegate returnarray:dict];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"请求网络出错:%@",error);
}
@end
下一篇博客我将会完整的教大家使用装饰设计模式中的类别和代理应用在一个小demo中。
如果你对本篇博客有任何疑问,随时提出。
王亦梁