ios - 在 nsoperation 内部使用 Runloop 执行异步任务

标签 ios multithreading nsurlsession nsoperation cfrunloop

我有一个用例,我需要使用 NSURLSession 下载许多文件。

为了防止 session 任务超时,我需要将它们放入操作队列中并限制并发下载量,这样它们就不会挨饿。

我的想法是,我将任务恢复加载到 nsoperation 中,并将它们加载到 nsoperationqueue 中,这将限制并发事件的数量。

问题是,当我调用 [taskresume] 时,代码将退出,并且 nsoperation 会认为自己已完成,即使我正在等待文件完成下载。

这是一些代码。

NSURLSessionDownloadTask *task = [session downloadTaskWithRequest: request 
completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {

     //move the file to a permanent location

     CFRunLoopStop(CFRunLoopGetCurrent());
}
//I have instantiated a class global NSOperation queue.
[imageDownloadQueue addOperationWithBlock:^void() {
     [task resume];
     CFRunLoopRun();
}];

如何在等待回调时让 nsoperation 线程保持事件状态?我也尝试过使用 nsrunloop 并向 NSMachPort 添加一个端口。这似乎没有帮助。

此外,在 NSURLSession 上设置 HttpMaximumConnectionsPerHost 也无济于事,因为超时计时器会在我恢复任务时启动。这意味着我将获得比以前更多的超时。

最佳答案

遗憾的是,我没有时间进行适当的修复,我需要尽快修复超时问题。我发现了一些有用的东西。

    //I have instantiated a class global NSOperation queue.
[imageDownloadQueue addOperationWithBlock:^void() {
     [task resume];
     while(task.state == NSURLSessionTaskStateRunning)
    {
         [NSThread sleepForTimeInterval:.1];
    }
    }];

由于 NSOperation 在后台线程上运行,因此我能够在任务运行时休眠该线程。这可以防止线程死亡,但任务将在它自己的线程上运行并且不会被阻塞。

关于ios - 在 nsoperation 内部使用 Runloop 执行异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39649971/

相关文章:

ios:NSURLSessionDataTask 并从不同 View 下载

ios - IDA 不显示符号信息

iphone - iOS - 调用者 viewController 的引用

ios - iOS中的自定义日期选择器

html - 如何使 iFrame 在 iPhone 6 中响应

java - 线程 hibernate 直到收到另一个类的通知

javascript - setInterval 的这种行为是否意味着 Javascript 中的多线程行为?

macos - NSURLSession 带宽限制

ios - 不确定为什么 NSURLSession 超时

android - 在 Activity 之间传递类的实例