请选择 进入手机版 | 继续访问电脑版
接着上一篇的内容往下讲
之前我们讲到NSUrlSession代理这一块:
代理8:
[Objective-C] 纯文本查看 复制代码
/*
 task完成之后的回调,成功和失败都会回调这里
 函数讨论:
 注意这里的error不会报告服务期端的error,他表示的是客户端这边的eroor,比如无法解析hostname或者连不上host主机。
 */
- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{   
    //根据task去取我们一开始创建绑定的delegate
    AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];

    // delegate may be nil when completing a task in the background
    if (delegate) {
        //把代理转发给我们绑定的delegate
        [delegate URLSession:session task:task didCompleteWithError:error];
        //转发完移除delegate
        [self removeDelegateForTask:task];
    }

    //自定义Block回调
    if (self.taskDidComplete) {
        self.taskDidComplete(session, task, error);
    }  
}
这个代理就是task完成了的回调,方法内做了下面这几件事:
  • 在这里我们拿到了之前和这个task对应绑定的AF的delegate:


[Objective-C] 纯文本查看 复制代码
- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {
  NSParameterAssert(task);

  AFURLSessionManagerTaskDelegate *delegate = nil;
  [self.lock lock];
  delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)];
  [self.lock unlock];

  return delegate;
}
  • 去转发了调用了AF代理的方法。这个等我们下面讲完NSUrlSession的代理之后会详细说。
  • 然后把这个AF的代理和task的绑定解除了,并且移除了相关的progress和通知:
[Objective-C] 纯文本查看 复制代码
- (void)removeDelegateForTask:(NSURLSessionTask *)task {
  NSParameterAssert(task);
  //移除跟AF代理相关的东西
  AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
  [self.lock lock];
  [delegate cleanUpProgressForTask:task];
  [self removeNotificationObserverForTask:task];
  [self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)];
  [self.lock unlock];
}

  • 调用了自定义的Blcok:self.taskDidComplete(session, task, error);
    代码还是很简单的,至于这个通知,我们等会再来补充吧。
NSURLSessionDataDelegate:
代理9:
[Objective-C] 纯文本查看 复制代码
//收到服务器响应后调用
- (void)URLSession:(NSURLSession *)session
          dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
    //设置默认为继续进行
    NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow;

    //自定义去设置
    if (self.dataTaskDidReceiveResponse) {
        disposition = self.dataTaskDidReceiveResponse(session, dataTask, response);
    }

    if (completionHandler) {
        completionHandler(disposition);
    }
}
官方文档翻译如下:
函数作用:
告诉代理,该data task获取到了服务器端传回的最初始回复(response)。注意其中的completionHandler这个block,通过传入一个类型为NSURLSessionResponseDisposition的变量来决定该传输任务接下来该做什么:
NSURLSessionResponseAllow 该task正常进行
NSURLSessionResponseCancel 该task会被取消
NSURLSessionResponseBecomeDownload 会调用URLSession:dataTask:didBecomeDownloadTask:方法来新建一个download task以代替当前的data task
NSURLSessionResponseBecomeStream 转成一个StreamTask
函数讨论:
该方法是可选的,除非你必须支持“multipart/x-mixed-replace”类型的content-type。因为如果你的request中包含了这种类型的content-type,服务器会将数据分片传回来,而且每次传回来的数据会覆盖之前的数据。每次返回新的数据时,session都会调用该函数,你应该在这个函数中合理地处理先前的数据,否则会被新数据覆盖。如果你没有提供该方法的实现,那么session将会继续任务,也就是说会覆盖之前的数据。
总结一下:
  • 当你把添加content-type的类型为multipart/x-mixed-replace那么服务器的数据会分片的传回来。然后这个方法是每次接受到对应片响应的时候会调被调用。你可以去设置上述4种对这个task的处理。
  • 如果我们实现了自定义Block,则调用一下,不然就用默认的NSURLSessionResponseAllow方式。
代理10:
[Objective-C] 纯文本查看 复制代码
//上面的代理如果设置为NSURLSessionResponseBecomeDownload,则会调用这个方法
- (void)URLSession:(NSURLSession *)session
          dataTask:(NSURLSessionDataTask *)dataTask
didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
{
    //因为转变了task,所以要对task做一个重新绑定
    AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask];
    if (delegate) {
        [self removeDelegateForTask:dataTask];
        [self setDelegate:delegate forTask:downloadTask];
    }
    //执行自定义Block
    if (self.dataTaskDidBecomeDownloadTask) {
        self.dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask);
    }
}
  • 这个代理方法是被上面的代理方法触发的,作用就是新建一个downloadTask,替换掉当前的dataTask。所以我们在这里做了AF自定义代理的重新绑定操作。
  • 调用自定义Block。
按照顺序来,其实还有个AF没有去实现的代理:
[Objective-C] 纯文本查看 复制代码
//AF没实现的代理
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask;
这个也是之前的那个代理,设置为NSURLSessionResponseBecomeStream则会调用到这个代理里来。会新生成一个NSURLSessionStreamTask来替换掉之前的dataTask。


文 /涂耀辉(简书作者)
原文链接:http://www.jianshu.com/p/f32bd79233da


举报 使用道具
| 回复

共 0 个关于本帖的回复 最后回复于 2017-1-12 21:57

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

本文内容不够精彩,我要自己发布

发布新帖

推荐阅读

    拥有的,不仅是技术!还有...
    联系 Email: support.36ji@qq.com

    • 关注酷站官方微博
      了解最新动态

    • 关注酷站微信公众号
      这里有好玩的讯息

    • 加入酷站交流群
      不断在这里成长

    © 2014-2017 36ji网络科技有限公司 . All rights reserved.
    京ICP备14001609号

    Archiver|    
    Powered by Discuz! X3.2 © 2001-2013 Comsenz Inc.
    快速回复 返回顶部 返回列表