使用时NSURLConnection
,您可以选择使用以下方式安排连接NSRunLoop
:
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
如果用户滚动,传递NSDefaultRunLoopMode
将有效地导致连接暂停,这对性能非常有用,因为用户体验从未受到下载的影响。
有没有办法获得类似的行为NSURLSession
?我已通读文档并尝试了各种配置会话的方法,但均未成功。
使用时NSURLConnection
,您可以选择使用以下方式安排连接NSRunLoop
:
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
如果用户滚动,传递NSDefaultRunLoopMode
将有效地导致连接暂停,这对性能非常有用,因为用户体验从未受到下载的影响。
有没有办法获得类似的行为NSURLSession
?我已通读文档并尝试了各种配置会话的方法,但均未成功。
NSURLSession
在“更高”级别工作,并且对于开发人员来说比使用NSURLConnection
.
我做了一些测试,我认为不可能控制 runloop 和 的模式NSURLSession
,因为它们似乎是由外部守护程序管理的,而不是由您的应用程序管理的(我只用 进行了测试NSURLSessionDownloadTask
)。
做这个简单的测试:
您将看到在您的应用程序暂停时下载已继续,因此当您启动时NSURLSession
,控件将传递给系统,在您的应用程序之外:这意味着工作的主要部分不会发生在内部 runLoop .
您唯一可以控制的是调度委托调用的串行队列(传递回您的应用程序)。委托调用排队等待执行(在主线程或后台线程上,您可以选择它),因为NSOperationQueue
使用 Grand Central Dispatch 对调用进行排队,我不确定用于此的运行循环模式,但我认为是继续研究的良好起点。
编辑:如果我没记错的话,在后台线程上进行的调度调用是在运行循环未运行的线程上进行的。事实上,如果你添加这一行
NSLog(@"%@", [[NSRunLoop currentRunLoop] currentMode]);
在上一个项目中的类的委托方法之一FLDownloader
上,您会看到没有运行模式(nil),当运行循环未运行时会发生这种情况。
如果有人再次遇到这个问题。您不能将下载任务安排到不同的运行循环中,但您可以在不同的运行循环模式下处理响应,这仍然大大提高了滚动时的性能。
[self performSelectorOnMainThread:@selector(requestDidFinishLoadingWithData:)
withObject:data
waitUntilDone:YES
modes:@[NSDefaultRunLoopMode]];