设计模式之装饰设计模式(二)delegate

这次我为大家介绍装饰设计模式中的delegate。

一. 什么是delegate

从委托方法的实现来看,委托方法的实现是在另外一个类中完成,即委托类的内部暴露了,与我们一般坚持的隐藏实现原则相违背。

从委托类的定义可以看出,委托与协议有一定的相似性。都采用protocol关键字来声明

,并且其中的方法都有optionalrequired,都需要对required方法和调用的optional方法进行实现。而不同的是在委托对象所在的类中需要定义一个delegate对象,并且为id类型。

二. delegate的用途

但是delegateprotocol没有关系。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 <NSURLConnectionDataDelegate>

@required
- (void)returnarray:(NSDictionary *)data;
<span style="font-family: Arial, Helvetica, sans-serif;">@end</span>

@property (nonatomic, retain)id<URLProtocol>delegate;

接着:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
 
    NSLog(@"数据加载完毕");
    
    //处理服务器返回的所有数据
    NSDictionary *dict =[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves
                                                          error:nil];
    [self.delegate returnarray:dict];
    
    
使得delegate得到请求的数据;

之后就可以在其他类中使用了。

在viewcontroller.m中

@interface ViewController ()<URLProtocol>
@end

- (void)viewDidLoad {
<p class="p1"><span class="s1">  </span><span class="s2">MyRequest</span><span class="s1"> *request =[[</span><span class="s2">MyRequest</span><span class="s1"> </span><span class="s3">alloc</span><span class="s1">] </span><span class="s3">init</span><span class="s1">];</span></p><p class="p1"><span class="s1">    request.</span><span class="s3">delegate</span><span class="s1"> = </span><span class="s4">self</span><span class="s1">;</span></p><p class="p1"><span class="s1">    request.</span><span class="s3">citystring</span><span class="s1"> =readArray[</span><span class="s3">_index</span><span class="s1">];</span></p><p class="p1"><span class="s1">    [request </span><span class="s3">startAsynrc</span><span class="s1">];</span></p>}


- (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 <Foundation/Foundation.h>
#import "ThirdViewController.h"
@protocol URLProtocol <NSURLConnectionDataDelegate>

@required
- (void)returnarray:(NSDictionary *)data;

@end

@interface MyRequest : NSMutableURLRequest <NSURLConnectionDataDelegate>
@property (nonatomic,retain) NSMutableData *responseData;
@property (nonatomic,retain) NSURLConnection *connection;
@property (nonatomic, retain)id<URLProtocol>delegate;
@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中。

如果你对本篇博客有任何疑问,随时提出。

王亦梁





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值