3

使用时NSURLConnection,您可以选择使用以下方式安排连接NSRunLoop

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

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

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

4

2 回答 2

3

NSURLSession在“更高”级别工作,并且对于开发人员来说比使用NSURLConnection.
我做了一些测试,我认为不可能控制 runloop 和 的模式NSURLSession,因为它们似乎是由外部守护程序管理的,而不是由您的应用程序管理的(我只用 进行了测试NSURLSessionDownloadTask)。
做这个简单的测试:

  1. 下载并执行这个 Github 项目
  2. 开始下载
  3. 打开“下载”控制器以查看下载状态
  4. 暂停应用
  5. 等一下
  6. 取消暂停应用

您将看到在您的应用程序暂停时下载已继续,因此当您启动时NSURLSession,控件将传递给系统,在您的应用程序之外:这意味着工作的主要部分不会发生在内部 runLoop .

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

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

NSLog(@"%@", [[NSRunLoop currentRunLoop] currentMode]);

在上一个项目中的类的委托方法之一FLDownloader上,您会看到没有运行模式(nil),当运行循环未运行时会发生这种情况。

于 2013-12-01T11:23:54.650 回答
0

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

[self performSelectorOnMainThread:@selector(requestDidFinishLoadingWithData:)
                       withObject:data
                    waitUntilDone:YES
                            modes:@[NSDefaultRunLoopMode]];
于 2015-10-01T07:52:07.490 回答