NSURLSession和NSDefaultRunLoopMode

时间:2013-11-20 14:07:47

标签: ios nsurlconnection nsurlsession nsurlsessionconfiguration

使用NSURLConnection时,您可以选择使用NSRunLoop来安排连接:

- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode

如果用户滚动,传递NSDefaultRunLoopMode将有效地导致连接暂停,这对性能很有用,因为用户体验从未受到下载的影响。

有没有办法让NSURLSession获得类似的行为?我已经阅读了文档并尝试了各种配置会话的方法,但没有成功。

2 个答案:

答案 0 :(得分:3)

NSURLSession在“上层”工作,对开发人员而言比使用NSURLConnection更简单。
我做了一些测试,我认为没有可能控制runloop和NSURLSession的模式,因为它们似乎是由外部守护进程而不是你的应用程序管理的(我只用{{1}进行了测试})。
做这个简单的测试:

  1. 下载并执行this Github project
  2. 开始下载
  3. 打开“下载”控制器以查看下载状态
  4. 暂停应用
  5. 等一下
  6. 取消暂停应用
  7. 您会看到在您的应用暂停时下载已继续,因此当您启动NSURLSessionDownloadTask时,控件将传递到您的应用外部的系统:这意味着工作的主要部分没有不在内部的runLoop中进行。

    您唯一可以控制的是调度委托调用的串行队列(传递回您的应用程序)。委托调用排队等待执行(在主要或后台线程上,您可以选择它),因为NSURLSession使用Grand Central Dispatch对调用进行排队,我不确定用于此的runloop模式,但我认为这是继续你的研究的一个很好的起点。

    编辑: 如果我没记错的话,在后台线程上进行的调度调用是在没有运行runloop的线程上进行的。实际上,如果你添加这一行

    NSOperationQueue

    在上一个项目的NSLog(@"%@", [[NSRunLoop currentRunLoop] currentMode]); 类的一个委托方法中,您将看到没有运行模式(nil),这在runloop未运行时发生。

答案 1 :(得分:0)

如果有人再遇到这个问题。您无法将下载任务安排到不同的运行循环中,但您可以在不同的运行循环模式下处理响应,这仍然可以在滚动时大大提高性能。

[self performSelectorOnMainThread:@selector(requestDidFinishLoadingWithData:)
                       withObject:data
                    waitUntilDone:YES
                            modes:@[NSDefaultRunLoopMode]];