什么时候设置NSURLSessionTaskDelegate?

时间:2016-12-05 09:11:44

标签: ios nsurlsession

我只是学习使用NSURLSession API,我发现在创建像这样的会话时我们只设置了NSURLSessionDelegate

self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

并且我们没有设置NSURLSessionTaskDelegate,但是NSURLSessionTaskDelegate方法也会被调用,似乎系统会调用对象上的NSURLSessionTaskDelegate方法遵守NSURLSessionDelegate?

更新演示代码

#import "ViewController.h"

@interface ViewController ()<NSURLSessionDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession* session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

    NSURLSessionDataTask* task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];

    [task resume];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{

}

1 个答案:

答案 0 :(得分:2)

如果我理解正确,你说的是你创建了一个在<NSURLSessionDelegate><NSURLSessionTaskDelegate>协议中实现方法的类,但是你只声明它实现了{{ 1}}协议。然后在创建会话时将其作为委托传递给您,并且您对为什么还调用会话任务委托方法感到困惑。

首先,每个会话只有一个代表。它处理与会话相关的事件以及与任务相关的事件。委托方法分为多个协议,以便于记录和理解。任务和会话委托方法之间的区别没有运行时重要性。

<NSURLSessionDelegate>课程由Apple预先编译。它没有使用您的标头编译,因此它不知道您传入的类对象的标头是否具有NSURLSession装饰。这些装饰仅在告诉编译器该类应包含这些方法的上下文中具有意义。如果将该类的实例传递给一个方法,该方法的参数类型表明传入的对象必须符合<NSURLSessionTaskDelegate>协议并且您的类没有,则编译将失败。同样,如果您缺少协议中的必需方法,则编译您的类将失败。然而,除了这两个目的,这些装饰基本上只适用于程序员和#39;益处。

此外,由于所有<NSURLSessionTaskDelegate>委托方法都是可选的,因此会话不能假定其委托将支持基于它声称符合的协议的任何特定方法。

由于这些原因,在运行时级别,会话通过询问委托对象是否支持该方法来确定是否调用每个委托方法。如果它说&#34; YES&#34;,则会话调用该方法。

因为您的类为任务和会话委托方法提供了实现,所以该类会自动显示&#34; YES&#34;当被问及是否支持这些方法时,NSURLSession会在适当的时候调用它们。