[英]iOS app crashes on NSOperationQueue when in Low Power Mode
I've written an app in Swift which crashes on the following lines, when in Low Power Mode.我在 Swift 中编写了一个应用程序,当处于低功耗模式时,它会在以下几行崩溃。 It's basically a request that runs on a background thread.
它基本上是一个在后台线程上运行的请求。 And some UI updates that's happening on the main thread.
还有一些在主线程上发生的 UI 更新。
I can't recreate the crash on my phone when in Low Power Mode, but according to my users this is the root cause.在低功耗模式下,我无法在手机上重现崩溃,但据我的用户称,这是根本原因。
// 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
})
I also found this on Apple.com:我也在 Apple.com 上找到了这个:
Users who wish to prolong their iPhone's battery life can enable Low Power Mode under Settings > Battery.
希望延长 iPhone 电池寿命的用户可以在“设置”>“电池”下启用“低电量模式”。 In Low Power Mode, iOS conserves battery life by enacting certain energy-saving measures.
在低电量模式下,iOS 通过制定某些节能措施来延长电池寿命。 For example, the system may:
例如,系统可能:
- Reduce CPU and GPU performance
降低 CPU 和 GPU 性能
- Pause discretionary and background activities, including networking
暂停自由裁量和后台活动,包括网络
- Reduce screen brightness
降低屏幕亮度
- Reduce the timeout for auto-locking the device
减少自动锁定设备的超时时间
- Disable Mail fetch
禁用邮件提取
- Disable motion effects
禁用运动效果
- Disable animated wallpapers
禁用动画壁纸
Sound like the problem is with Pause discretionary and background activities, including networking ?听起来问题在于暂停自由裁量和后台活动,包括网络?
How can I make the request in the background and update the UI on the mainthread meanwhile when Low Power Mode is enabled (I have some UIView.animateWithDuration going)?当启用低功耗模式时,如何在后台发出请求并更新主线程上的 UI(我有一些 UIView.animateWithDuration 正在进行)? The user will always have the app in the foreground when these methods are run, does this mean I should run the request on the main thread?
当这些方法运行时,用户将始终在前台运行应用程序,这是否意味着我应该在主线程上运行请求?
Below is the Crash report from Fabric/Crashlytics:以下是 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
Here's the top of the stack trace from the thread which caused the crash:这是导致崩溃的线程的堆栈跟踪顶部:
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
...
It looks like the crash happened inside of the following closure:看起来崩溃发生在以下闭包内:
{ data, response, error -> Void in
self.analyzeResults(data!)
}
but before entering the analyzeResults(dataToParse: NSData)
function.但在进入
analyzeResults(dataToParse: NSData)
函数之前。 The only obvious issue at the line self.analyzeResults(data!)
is that you're force-unwrapping data
without checking that it's present. self.analyzeResults(data!)
行中唯一明显的问题是您在不检查data
是否存在的情况下强制展开data
。
As you noticed, Apple mentions that under the Low Power Mode the system may:正如您所注意到的,Apple 提到在低功耗模式下系统可能会:
Pause discretionary and background activities, including networking
暂停自由裁量和后台活动,包括网络
So it's possible that because of the Low Power Mode networking paused for your users which led to timeouts for the network requests.因此,可能是因为您的用户的低功耗模式网络暂停,导致网络请求超时。 With these timeouts your
data
variable becomes nil
and then you get the crash.随着这些超时,您的
data
变量变为nil
,然后您就会崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.