首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NSURLSession dataTaskWithURL

NSURLSession dataTaskWithURL
EN

Stack Overflow用户
提问于 2014-07-10 08:23:14
回答 3查看 706关注 0票数 0

我使用的是NSURLSession dataTaskWithURL:completionHandler。看起来completionHandler是在一个与调用dataTaskWithURL的线程(在我的例子中是主线程)不同的线程中执行的。所以我的问题是,由于它是异步的,是否有可能主线程退出,但completionHandler线程仍然在运行,因为响应没有返回,这是我试图避免的情况。如果可能发生这种情况,我应该如何解决这个问题?顺便说一句,我将其构建为一个框架,而不是一个application.Thanks。

EN

回答 3

Stack Overflow用户

发布于 2016-05-16 06:31:13

在问题的第一部分,您似乎不确定完成处理程序是否在不同的线程上运行。为了确认这一点,让我们看一下NSURLSession Class Reference。如果我们查看“创建会话”部分,我们可以在以下方法的描述中看到答案。

代码语言:javascript
运行
复制
+ sessionWithConfiguration:delegate:delegateQueue:

Swift

代码语言:javascript
运行
复制
init(configuration configuration: NSURLSessionConfiguration,
      delegate delegate: NSURLSessionDelegate?,
 delegateQueue queue: NSOperationQueue?)

Objective-C

代码语言:javascript
运行
复制
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
                                  delegate:(id<NSURLSessionDelegate>)delegate
                             delegateQueue:(NSOperationQueue *)queue

在NSOperationQueue队列参数的参数表中,有以下引号。

用于调度委托调用和完成处理程序的操作队列。队列不必是串行队列。如果为nil,会话将创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。

因此,我们可以看到默认行为是提供一个队列,无论是来自开发人员还是作为默认的类行为。同样,我们可以在+ sessionWithConfiguration:方法的注释中看到这一点

讨论

调用此方法等同于使用nil委托和队列调用sessionWithConfiguration:delegate:delegateQueue:。

如果你想了解更多信息,你应该阅读苹果的Concurrency Programming Guide。这也有助于从总体上理解Apple的线程化方法。

因此,来自- dataTaskWithURL:completionHandler:的完成处理程序在不同的队列上运行,队列通常提供自己的线程。这就引出了你问题的主要部分。当完成处理程序仍在运行时,主线程是否可以退出?

简而言之,答案是否定的,但为什么呢?

为了回答这个问题,我们再次转向Apple的文档,这是一个每个人都应该在应用程序开发人员职业生涯早期阅读的文档!

The App Programming Guide

主运行循环

应用程序的主运行循环处理所有与用户相关的事件。UIApplication对象在启动时设置主运行循环,并使用它来处理事件和处理对基于视图的接口的更新。顾名思义,main run循环在应用程序的主线程上执行。此行为可确保按接收用户相关事件的顺序连续处理这些事件。

所有的用户交互都发生在主线程上--没有主线程,没有主运行循环,没有应用程序!所以你提到的可能的情况永远不应该存在!

Apple似乎更关心你在主线程上做后台工作。查看“将工作移出主线程”一节...

请务必限制您在应用程序主线程上所做的工作类型。主线程是你的应用程序处理触摸事件和其他用户输入的地方。为了确保您的应用程序始终响应用户,您不应该使用主线程来执行长时间运行或可能无限制的任务,例如访问网络的任务。相反,您应该始终将这些任务移动到后台线程上。执行此操作的首选方法是使用中央调度中心(GCD)或NSOperation对象异步执行任务。

我知道这个答案是长篇大论的,但我觉得有必要在回答你的问题时提供洞察力和细节-“为什么”同样重要,而且它是很好的评论:)

票数 1
EN

Stack Overflow用户

发布于 2014-12-10 19:39:27

默认情况下,NSURLSessionTasks总是在后台运行,这就是为什么我们有完成处理程序的原因,当我们从Web服务获得响应时,可以使用它。

如果您没有得到任何响应,请查看您的请求URL以及HTTPHeaderFields是否设置正确。

粘贴您的代码,以便我们可以帮助它

票数 0
EN

Stack Overflow用户

发布于 2015-07-17 21:27:24

我刚问了同样的问题。然后找到了答案。完成处理程序的线程设置在NSURLSession的初始化中。

documentation

代码语言:javascript
运行
复制
init(configuration configuration: NSURLSessionConfiguration,
     delegate delegate: NSURLSessionDelegate?,
     delegateQueue queue: NSOperationQueue?)`

队列-用于调度委托调用和完成处理程序的队列。如果为nil,会话将创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。*

我的代码设置为在主线程上完成:

代码语言:javascript
运行
复制
var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())

(在Swift中显示,Objective-C相同)如果这不能解决问题,可能会发布更多代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24665702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档