【问题标题】:iOS app crashes on NSOperationQueue when in Low Power Mode在低功耗模式下,iOS 应用程序在 NSOperationQueue 上崩溃
【发布时间】:2016-06-28 08:27:35
【问题描述】:

我用 Swift 编写了一个应用程序,当处于低功耗模式时,它会在以下几行崩溃。它基本上是在后台线程上运行的请求。还有一些在主线程上发生的 UI 更新。

在低功耗模式下,我无法在手机上重现崩溃,但根据我的用户的说法,这是根本原因。

// Run the request on a background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
   self.runRequestOnBackgroundThread(request)
});

func runRequestOnBackgroundThread(request: NSMutableURLRequest) {
    //We need to update the UI on the mainthread/ ONLY THE UI
    dispatch_async(dispatch_get_main_queue(), {
        self.scanInProgress()
    })
    let session = NSURLSession.sharedSession()
    // run the request
    let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        self.analyzeResults(data!)
    })
    task.resume()
}


func analyzeResults(dataToParse: NSData) {
    // Update UI on the main thread and analyze data from request
    // Line 491 below this line
    dispatch_async(dispatch_get_main_queue(), {
        //Here goes some regex
    })

我还在 Apple.com 上找到了这个:

希望延长 iPhone 电池寿命的用户可以启用 Low 设置 > 电池下的电源模式。在低功耗模式下,iOS 节省 通过制定某些节能措施来延长电池寿命。例如, 系统可能:

  • 降低 CPU 和 GPU 性能
  • 暂停自主活动和后台活动,包括社交
  • 降低屏幕亮度
  • 减少自动锁定设备的超时时间
  • 禁用邮件提取
  • 禁用运动效果
  • 禁用动画壁纸

听起来问题出在 暂停自主活动和后台活动,包括网络

如何在启用低功耗模式的同时在后台发出请求并更新主线程上的 UI(我有一些 UIView.animateWithDuration 正在运行)?运行这些方法时,用户将始终将应用程序置于前台,这是否意味着我应该在主线程上运行请求?

以下是 Fabric/Crashlytics 的崩溃报告:

#-1. com.apple.main-thread
0  libsystem_platform.dylib       0x18428d8b0 _platform_memcmp + 32
1  CoreFoundation                 0x1845fe710 __CFStringEqual + 256
2  CoreFoundation                 0x1845fe710 __CFStringEqual + 256
3  CoreFoundation                 0x18450ebf4 CFEqual + 400
4  CoreFoundation                 0x184670314 __NSCacheKeyEqual + 12
5  libcache.dylib                 0x184006bcc _entry_get_optionally_checking_collisions + 164
6  libcache.dylib                 0x1840051b8 cache_get_and_retain + 132
7  CoreFoundation                 0x18455f22c -[NSCache objectForKey:] + 68
8  CoreUI                         0x189146660 -[CUIStructuredThemeStore _canGetRenditionWithKey:isFPO:lookForSubstitutions:] + 360
9  CoreUI                         0x189168f48 -[CUICatalog _resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:] + 1416
10 CoreUI                         0x1891680fc -[CUICatalog namedLookupWithName:scaleFactor:deviceIdiom:deviceSubtype:sizeClassHorizontal:sizeClassVertical:] + 148
11 UIKit                          0x189b7d994 __98-[_UIAssetManager imageNamed:scale:idiom:subtype:cachingOptions:sizeClassPair:attachCatalogImage:]_block_invoke + 424
12 UIKit                          0x189b7d734 -[_UIAssetManager imageNamed:scale:idiom:subtype:cachingOptions:sizeClassPair:attachCatalogImage:] + 212
13 UIKit                          0x189c90584 -[UIImageAsset imageWithTraitCollection:] + 404
14 UIKit                          0x1896cf058 -[UIImageView _resolveImageForTrait:] + 460
15 UIKit                          0x1896ce928 -[UIImageView _didMoveFromWindow:toWindow:] + 212
16 UIKit                          0x18931ad7c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
17 UIKit                          0x1893a04f8 -[UIControl _didMoveFromWindow:toWindow:] + 80
18 UIKit                          0x18931ad7c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 760
19 UIKit                          0x18931a310 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 152
20 Foundation                     0x184f4d500 -[NSISEngine withBehaviors:performModifications:] + 168
21 UIKit                          0x18931a194 -[UIView(Hierarchy) _postMovedFromSuperview:] + 532
22 UIKit                          0x189327b80 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1784
23 UIKit                          0x189420b34 -[UITransitionView transition:fromView:toView:removeFromView:] + 1544
24 UIKit                          0x189420458 -[UIViewControllerBuiltinTransitionViewAnimator animateTransition:] + 2780
25 UIKit                          0x18967ab7c __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 2228
26 UIKit                          0x1895d0b70 _runAfterCACommitDeferredBlocks + 292
27 UIKit                          0x1895de030 _cleanUpAfterCAFlushAndRunDeferredBlocks + 92
28 UIKit                          0x189311c24 _afterCACommitHandler + 96
29 CoreFoundation                 0x1845e4588 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
30 CoreFoundation                 0x1845e232c __CFRunLoopDoObservers + 372
31 CoreFoundation                 0x1845e275c __CFRunLoopRun + 928
32 CoreFoundation                 0x184511680 CFRunLoopRunSpecific + 384
33 GraphicsServices               0x185a20088 GSEventRunModal + 180
34 UIKit                          0x189388d90 UIApplicationMain + 204
35 TestDrive                      0x1000a32ec main (AppDelegate.swift:15)
36 libdispatch.dylib              0x1840b28b8 (Missing)

#0. com.apple.libdispatch-manager
0  libsystem_kernel.dylib         0x1841d14fc kevent_qos + 8
1  libdispatch.dylib              0x18409494c _dispatch_mgr_invoke + 232
2  libdispatch.dylib              0x1840837bc _dispatch_source_invoke + 50

#1. com.twitter.crashlytics.ios.MachExceptionServer
0  TestDrive                      0x1000d94c8 CLSProcessRecordAllThreads + 4296103112
1  TestDrive                      0x1000d94c8 CLSProcessRecordAllThreads + 4296103112
2  TestDrive                      0x1000d98e8 CLSProcessRecordAllThreads + 4296104168
3  TestDrive                      0x1000ca5a8 CLSHandler + 4296041896
4  TestDrive                      0x1000c572c CLSMachExceptionServer + 4296021804
5  libsystem_pthread.dylib        0x184297b28 _pthread_body + 156
6  libsystem_pthread.dylib        0x184297a8c _pthread_body + 154
7  libsystem_pthread.dylib        0x184295028 thread_start + 4

#2. com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0x1841b54bc mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1841b5338 mach_msg + 72
2  CoreFoundation                 0x1845e4ac0 __CFRunLoopServiceMachPort + 196
3  CoreFoundation                 0x1845e27c4 __CFRunLoopRun + 1032
4  CoreFoundation                 0x184511680 CFRunLoopRunSpecific + 384
5  CFNetwork                      0x184c81434 +[NSURLConnection(Loader) _resourceLoadLoop:] + 412
6  Foundation                     0x184fefc40 __NSThread__start__ + 1000
7  libsystem_pthread.dylib        0x184297b28 _pthread_body + 156
8  libsystem_pthread.dylib        0x184297a8c _pthread_body + 154
9  libsystem_pthread.dylib        0x184295028 thread_start + 4

#3. com.apple.CFSocket.private
0  libsystem_kernel.dylib         0x1841d0368 __select + 8
1  CoreFoundation                 0x1845eb028 __CFSocketManager + 648
2  libsystem_pthread.dylib        0x184297b28 _pthread_body + 156
3  libsystem_pthread.dylib        0x184297a8c _pthread_body + 154
4  libsystem_pthread.dylib        0x184295028 thread_start + 4

#4. com.apple.coremedia.player.async
0  libsystem_kernel.dylib         0x1841b54f8 semaphore_wait_trap + 8
1  libdispatch.dylib              0x18409255c _dispatch_semaphore_wait_slow + 244
2  MediaToolbox                   0x18a119454 fpa_AsyncMovieControlThread + 1948
3  CoreMedia                      0x1865ea980 figThreadMain + 272
4  libsystem_pthread.dylib        0x184297b28 _pthread_body + 156
5  libsystem_pthread.dylib        0x184297a8c _pthread_body + 154
6  libsystem_pthread.dylib        0x184295028 thread_start + 4

#5. com.apple.CoreMotion.MotionThread
0  libsystem_kernel.dylib         0x1841b54bc mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1841b5338 mach_msg + 72
2  CoreFoundation                 0x1845e4ac0 __CFRunLoopServiceMachPort + 196
3  CoreFoundation                 0x1845e27c4 __CFRunLoopRun + 1032
4  CoreFoundation                 0x184511680 CFRunLoopRunSpecific + 384
5  CoreFoundation                 0x18455ee2c CFRunLoopRun + 112
6  CoreMotion                     0x18a03e22c (null) + 95286384
7  libsystem_pthread.dylib        0x184297b28 _pthread_body + 156
8  libsystem_pthread.dylib        0x184297a8c _pthread_body + 154
9  libsystem_pthread.dylib        0x184295028 thread_start + 4

#6. Thread
0  libsystem_kernel.dylib         0x1841d0b6c __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x184295530 _pthread_wqthread + 1284
2  libsystem_pthread.dylib        0x184295020 start_wqthread + 4

#7. com.apple.camera.avcapturesession
0  libsystem_kernel.dylib         0x1841b54bc mach_msg_trap + 8
1  libsystem_kernel.dylib         0x1841b5338 mach_msg + 72
2  CoreFoundation                 0x1845e4ac0 __CFRunLoopServiceMachPort + 196
3  CoreFoundation                 0x1845e27c4 __CFRunLoopRun + 1032
4  CoreFoundation                 0x184511680 CFRunLoopRunSpecific + 384
5  AVFoundation                   0x18a8e61dc -[AVRunLoopCondition _waitInMode:untilDate:] + 432
6  AVFoundation                   0x18a8ce960 -[AVCaptureSession _stopFigCaptureSession] + 412
7  AVFoundation                   0x18a8ceb34 -[AVCaptureSession _setRunning:] + 216
8  CameraKit                      0x18d1dcce0 __35-[CMKCaptureController stopPreview]_block_invoke
9  libdispatch.dylib              0x184081630 _dispatch_call_block_and_release + 24
10 libdispatch.dylib              0x1840815f0 _dispatch_client_callout + 16
11 libdispatch.dylib              0x18408d634 _dispatch_queue_drain + 864
12 libdispatch.dylib              0x1840850f4 _dispatch_queue_invoke + 464
13 libdispatch.dylib              0x1840815f0 _dispatch_client_callout + 16
14 libdispatch.dylib              0x18408fa88 _dispatch_root_queue_drain + 2140
15 libdispatch.dylib              0x18408f224 _dispatch_worker_thread3 + 112
16 libsystem_pthread.dylib        0x184295470 _pthread_wqthread + 1092
17 libsystem_pthread.dylib        0x184295020 start_wqthread + 4

Crashed: NSOperationQueue 0x15d5754b0 :: NSOperation 0x15e9b8460 (QOS: LEGACY)
0  TestDrive                      0x1000b597c VerifyDriverViewController.(runRequestOnBackgroundThread(NSMutableURLRequest) -> ()).(closure #2) (VerifyDriverViewController.swift:491)
1  CFNetwork                      0x184c0f344 __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 32
2  CFNetwork                      0x184c21cc4 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 296
3  Foundation                     0x184fd4334 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 16
4  Foundation                     0x184f27100 -[NSBlockOperation main] + 96
5  Foundation                     0x184f17348 -[__NSOperationInternal _start:] + 604
6  Foundation                     0x184fd6728 __NSOQSchedule_f + 224
7  libdispatch.dylib              0x1840815f0 _dispatch_client_callout + 16
8  libdispatch.dylib              0x18408d634 _dispatch_queue_drain + 864
9  libdispatch.dylib              0x1840850f4 _dispatch_queue_invoke + 464
10 libdispatch.dylib              0x18408f504 _dispatch_root_queue_drain + 728
11 libdispatch.dylib              0x18408f224 _dispatch_worker_thread3 + 112
12 libsystem_pthread.dylib        0x184295470 _pthread_wqthread + 1092
13 libsystem_pthread.dylib        0x184295020 start_wqthread + 4

#9. Thread
0  libsystem_kernel.dylib         0x1841d0b6c __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x184295530 _pthread_wqthread + 1284
2  libsystem_pthread.dylib        0x184295020 start_wqthread + 4

#10. Thread
0  libsystem_kernel.dylib         0x1841d0b6c __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x184295530 _pthread_wqthread + 1284
2  libsystem_pthread.dylib        0x184295020 start_wqthread + 4

#11. Thread
0  libsystem_kernel.dylib         0x1841d0b6c __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x184295530 _pthread_wqthread + 1284
2  libsystem_pthread.dylib        0x184295020 start_wqthread + 4

【问题讨论】:

  • 第 491 行是哪一行?
  • 您在完成闭包中强制解包数据:self.analyzeResults(data!)。您需要先检查是否没有错误或检查数据是否不为零。我建议人们不要强制打开包装,因为这是不好的做法。
  • @kennytm 抱歉,第 491 行是:dispatch_async(dispatch_get_main_queue(), { //这里有一些正则表达式 })
  • 您知道崩溃发生时应用是否可见(在前台)?
  • 崩溃似乎与网络无关。它与 UI 更新相关,类似于 UIImage imagedNames。 diapatch_async 中的代码是什么

标签: ios swift nsurlsession nsoperation nsoperationqueue


【解决方案1】:

这是导致崩溃的线程的堆栈跟踪顶部:

Crashed: NSOperationQueue 0x15d5754b0 :: NSOperation 0x15e9b8460 (QOS: LEGACY)
0  TestDrive                      0x1000b597c VerifyDriverViewController.(runRequestOnBackgroundThread(NSMutableURLRequest) -> ()).(closure #2) (VerifyDriverViewController.swift:491)
1  CFNetwork                      0x184c0f344 __75-[__NSURLSessionLocal taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 32
...

看起来崩溃发生在以下闭包内:

{ data, response, error -> Void in
    self.analyzeResults(data!)
}

但在进入analyzeResults(dataToParse: NSData) 函数之前。 self.analyzeResults(data!) 行唯一明显的问题是,您在没有检查它是否存在的情况下强制展开 data

如您所见,Apple 提到在低功耗模式下系统可能:

暂停自主活动和后台活动,包括社交

因此,由于低功耗模式,您的用户的网络可能会暂停,从而导致网络请求超时。随着这些超时,您的data 变量变为nil,然后您就会崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    相关资源
    最近更新 更多