为什么连接回iOS后台会话会花费太长时间等待锁,导致应用程序崩溃?

为什么连接回iOS后台会话会花费太长时间等待锁,导致应用程序崩溃?,ios,objective-c,crash,nsurlsession,Ios,Objective C,Crash,Nsurlsession,为什么通过NSURLSession的配置连接会花费很长时间,以至于在启动时会导致应用程序崩溃:“未能及时启动” 我在许多iOS应用程序中看到过类似的崩溃转储,包括纽约时报iOS应用程序和Evernote应用程序 [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:queue] 以下是堆栈跟踪: Thread 0: 0 libsystem_kernel.dylib

为什么通过NSURLSession的配置连接会花费很长时间,以至于在启动时会导致应用程序崩溃:“未能及时启动”

我在许多iOS应用程序中看到过类似的崩溃转储,包括纽约时报iOS应用程序和Evernote应用程序

[NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:queue]
以下是堆栈跟踪:

Thread 0:
0   libsystem_kernel.dylib          0x3afb7aa0 semaphore_wait_trap + 8
1   libdispatch.dylib               0x3af04d3d _dispatch_semaphore_wait_slow + 173
2   CFNetwork                       0x2febd8e3 -[__NSCFBackgroundSessionBridge setupBackgroundSession] + 379
3   CFNetwork                       0x2fef18a1 +[__NSCFSessionBridge bridgeForConfiguration:session:queue:] + 153
4   CFNetwork                       0x2fef6497 -[__NSCFURLSession initWithConfiguration:delegate:delegateQueue:] + 395
5   CFNetwork                       0x2fef6eb7 +[__NSCFURLSession sessionWithConfiguration:delegate:delegateQueue:] + 295

基本上有两件事需要记住:

  • 启动后,您只有几秒钟的时间来完成启动过程。任何长时间运行的代码都应该在应用程序启动后异步调用

  • 绝对确保回调/块/闭包等中的任何UI代码。。。在主线程上调用。你必须强迫它这样做


  • @亨利·阿塞利,谢谢,这很有道理,我同意你的指导方针。我不清楚的是,为什么sessionWithConfiguration:delegate:delegateQueue:API需要很长时间,它需要异步,以便在启动时不会阻塞应用程序。该API的语义并不意味着它可以是一个长时间运行的调用,但也许我遗漏了一些东西。我还面临着与精确堆栈跟踪相同的问题。无法找出根本原因@Rayyan,你能解决这个问题吗?我将调用移动到后台线程上异步运行,这样操作系统就不会因此而终止应用程序。但是,sessionWithConfiguration调用将挂起并且永远不会返回。这种情况很少发生,但一旦设备进入不良状态,它就会一直挂在该设备上@kkumpavat,这也是你看到的吗?我怀疑这是iOS中的一个bug。是的,我也怀疑这是iOS中的一个bug。这种情况很少发生,一旦iOS进入这种糟糕的状态,每次执行都会挂起“sessionWithConfiguration:delegate:delegateQueue:”。另外,将调用移动到异步运行也没有帮助,因为会话从未初始化,我们将无法执行网络任务。我似乎在iOS 8.3上也遇到了这个问题。你有没有制定过解决方案或变通办法?我想我可能只是在后台队列上这样做,因为我不需要在启动时立即使用它。我在iOS 8.3上也有这个问题(以前在8.2上正常工作)。基本上,如果我有一个大文件后台上传在进行中,应用程序被杀死,它将始终挂起在重新启动,直到我重新启动设备。我目前的解决方法是将一些标志存储在NSUserDefaults中,并在接收UrlSessiondFinishEventsforBackgroundUrlSession通知时重置它们。之后,可以安全地调用sessionWithConfiguration。这是一个风险,通知将永远不会收到,我的标志将永久禁用服务。