zoukankan      html  css  js  c++  java
  • iOS学习笔记之回调(二)

    写在前面

    上一篇学习笔记中简单介绍了通过目标-动作对实现回调操作:创建两个对象timer和logger,将logger设置为timer的目标,timer定时调用logger的sayOuch函数。在这个例子中,timer的任务比较简单,只完成一项任务:在指定的时刻触发事件。在这种情况下,适合选择目标-动作来实现回调,但这种方式不适合要发送多个回调的情况。

    辅助对象

    辅助对象是另一种实现回调的方式。在应用开始等待前,要求当等待的特定事件发生时,向遵守相应协议的辅助对象发送消息。委托对象数据源是常见的辅助对象。

    案例

    假定我们创建一个NSURLConnection对象并从一个给定的url中获取数据,然后等待回调。回调函数被触发的时机包括:获得数据、数据获取完成、获取数据失败等。
    可见,如果只是简单的目标-动作队机制,无法实现这些复杂的回调。因此,我们为NSURLConnection对象设置一个辅助对象,这个辅助对象专门负责处理特定事件发生之后的事情,也就是说,当特定的事件发生后,NSURLConnection对象会向辅助对象发送消息。这些消息包含在一套协议中。协议和接口概念有些相似,协议就是一组方法的声明,遵循相应协议的类必须实现协议中的方法(可以只实现部分方法)。
    我们假定让Logger类型的对象成为NSURLConnection对象的辅助对象,也就是说,将Logger对象赋给NSURLConne对象的成员变量delegate。Logger类必须实现NSURLConnection协议中的部分活全部方法。关系图如下:

    首先更改Logger类的代码,由于要接收数据,因此为Logger类添加一个NSMutableData类型的属性,如下:
    Logger.h

    @property NSMutableData *incomingData;
    

    然后在Logger.m中实现协议中的部分方法

    //收到一定字节数的数据后会被调用
    - (void)connection:(NSURLConnection *)connection
        didReceiveData:(NSData *)data
    {
        NSLog(@"received %lu bytes", [data length]);
        
        if (!self.incomingData) {
            self.incomingData = [[NSMutableData alloc] init];
        }
        
        [self.incomingData appendData: data];
    }
    
    //最后一部分数据处理完毕后,会被调用
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        NSLog(@"Got it all!");
        
        NSString *string = [[NSString alloc] initWithData:self.incomingData
                                                 encoding:NSUTF8StringEncoding];
        self.incomingData = nil;
        NSLog(@"string has %lu characters", [string length]);
        
        NSLog(@"The whole string is %@", string);
    }
    
    //获取数据失败时,会被调用
    - (void)connection:(NSURLConnection *)connection
      didFailWithError:(NSError *)error
    {
        NSLog(@"connection failed: %@",[error localizedDescription]);
        self.incomingData = nil;
    }
    

    在main函数中创建Logger对象和NSURLConnection,并将前者设置为后者的辅助对象:

    Logger *logger = [[Logger alloc] init];
            
            NSURL *url = [NSURL URLWithString:@"http://www.cnblogs.com/scut-linmaojiang/p/iOS-huidiao-y.html"];
                    
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            NSURLConnection *fetchConn = [[NSURLConnection alloc]
                                                   initWithRequest:request
                                                          delegate:logger
                                                  startImmediately:YES];
    

    如上所示,当NSURLConnection对象fetchConn从指定url获取数据时,将logger对象设置为它的辅助对象,也就是将logger作为fetchConn对象的委托。fetchCon获取数据过程中的各种状态会触发logger执行对应状态下的方法。利用断点设置,我们可以知道正常情况下,logger执行回调函数的顺序为:
    1、接收到数据,执行

    - (void)connection:(NSURLConnection *)connection
        didReceiveData:(NSData *)data
    

    运行截图如下:

    2、最后一部分数据处理完毕,执行

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    

    运行截图如下:


    ...

    url是上一篇笔记的地址,获取到的数据是以html格式显示的

    如果计算机处理断网状态,那么fetchConn将无法获取到数据,此时logger将执行下面的回调函数

    - (void)connection:(NSURLConnection *)connection
      didFailWithError:(NSError *)error
    

    运行截图如下:

    总结

    对比目标-动作对机制和辅助对象机制这两种实现回调的方式可知,当某个对象只提供了一个回调函数时,使用目标-动作对较为合适。而当某个对象要提供多个回调函数,也就说要接收多个回调信息时,使用遵循相应协议的辅助对象较为合理。

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
  • 相关阅读:
    微信小程序wx:key以及wx:key=" *this"详解:
    JavaScript实现按照指定长度为数字前面补零输出的方法
    多行文字溢出点点点的3中实现方法
    C#多态“说来也说”——逻辑层BLL中的多态使用
    .NET文件并发与RabbitMQ(初探RabbitMQ)
    StackExchange.Redis客户端读写主从配置,以及哨兵配置。
    RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
    StackExchange.Redis帮助类解决方案RedisRepository封装(散列Hash类型数据操作)
    StackExchange.Redis帮助类解决方案RedisRepository封装(字符串类型数据操作)
    StackExchange.Redis帮助类解决方案RedisRepository封装(基础配置)
  • 原文地址:https://www.cnblogs.com/scut-linmaojiang/p/iOS-huidiao-er.html
Copyright © 2011-2022 走看看