我正在使用NSURLSession dataTaskWithURL:completionHandler。看起来,completionHandler是在一个线程中执行的,该线程与调用dataTaskWithURL的线程(在我的情况下,它是主线程)不同。所以我的问题是,因为它是异步的,主线程是否有可能退出,但是由于响应没有返回,所以completionHandler线程仍在运行,这是我试图避免的情况。如果发生这种情况,我该如何解决这个问题呢?顺便说一句,我正在构建这个框架,而不是应用程序。谢谢。
答案 0 :(得分:1)
在您的问题的第一部分中,您似乎不确定完成处理程序是否在另一个线程上运行。要确认这一点,请查看NSURLSession Class Reference。如果我们看一下"创建一个会话"我们可以在描述中看到以下方法的答案。
+ sessionWithConfiguration:delegate:delegateQueue:
<强>夫特强>
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)
<强>目标C 强>
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
delegate:(id<NSURLSessionDelegate>)delegate
delegateQueue:(NSOperationQueue *)queue
在NSOperationQueue队列参数的参数表中,引用如下。
用于调度委托调用和完成处理程序的操作队列。队列不必是串行队列。如果为nil,则会话创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。
因此我们可以看到默认行为是提供队列,无论是来自开发人员还是作为默认的类行为。我们再次可以在方法+ sessionWithConfiguration:
<强>讨论强>
调用此方法相当于调用 sessionWithConfiguration:delegate:delegateQueue:带有nil委托 和队列。
如果您想了解更多信息,请阅读Apple的Concurrency Programming Guide。这对于理解Apple的一般线程方法也很有用。
因此- dataTaskWithURL:completionHandler:
的完成处理程序在不同的队列上运行,队列通常提供自己的线程。这是您问题的主要组成部分。主线程可以退出,而完成处理程序仍在运行吗?
简明的答案是否定的,但为什么呢?
要回答这个问题,我们再次转向Apple的文档,以及每个人都应该在应用开发者职业生涯早期阅读的文档!
主要运行循环
应用程序的主运行循环处理所有与用户相关的事件。该 UIApplication对象在启动时设置主运行循环并使用 它处理事件并处理基于视图的界面的更新。如 顾名思义,主运行循环在app的main上执行 线。此行为可确保处理与用户相关的事件 按顺序排列。
所有用户交互发生在主线程上 - 没有主线程,没有主运行循环,没有应用程序!因此,您提出的可能情况应该永远不存在!
Apple似乎更关心你在主线程上做背景工作。查看部分&#34;将工作移离主线程&#34; ...
请务必限制您在主线程上所做的工作类型 应用程序。主线程是您的应用处理触摸事件和其他事件的位置 用户输入。为确保您的应用始终对用户做出响应, 你永远不应该使用主线程来执行长时间运行或 可能无限制的任务,例如访问网络的任务。 相反,您应该始终将这些任务移到后台线程上。 这样做的首选方法是使用Grand Central Dispatch(GCD)或 NSOperation对象以异步方式执行任务。
我知道这个答案很长,但我觉得有必要在回答你的问题时提供洞察力和细节 - &#34;为什么&#34;同样重要,这是很好的评论:)。
答案 1 :(得分:0)
NSURLSessionTasks默认情况下总是在后台运行,这就是为什么我们有完成处理程序,当我们从Web服务获得响应时可以使用它。
如果您没有得到任何回复,请浏览您的请求网址以及HTTPHeaderFields是否设置正确。
粘贴您的代码,以便我们可以提供帮助
答案 2 :(得分:0)
我刚问了同样的问题。然后想出了答案。完成处理程序的线程在NSURLSession的init中设置。
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)`
queue - 用于调度委托调用和完成处理程序的队列。如果为nil,则会话创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。*
我在主线程上设置完成的代码:
var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())
(在Swift中显示,Objective-C相同)如果没有解决,可能会发布更多代码。