应用程序执行后台抓取completionHandler后崩溃

我已经更新了我们的iOS 7应用程序,并添加了后台获取function。 但是,我注意到一些崩溃,因为这个function。 在后台访存调用完成之后,完成处理程序块将以新/无数据执行。 这导致了我的自定义导航NavigationBar的“layoutSubviews”的调用,有时应用程序崩溃与下面的堆栈跟踪。 我自己无法重现这个问题,但不断从我们的用户接收这些崩溃日志。 任何帮助,将不胜感激。

Thread 0 Crashed: 0 libsystem_platform.dylib 0x39cba486 _platform_memmove$VARIANT$Swift + 102 1 Foundation 0x2fce8f47 -[NSData(NSData) getBytes:range:] + 419 2 CoreFoundation 0x2f30637d CFDataGetBytes + 205 3 ImageIO 0x300e7357 CGImageReadGetBytesAtOffset + 283 4 ImageIO 0x300e7231 CGImageReadSessionGetBytes + 29 5 ImageIO 0x3022baeb read_fn + 23 6 ImageIO 0x300e7189 png_read_sig + 45 7 ImageIO 0x300e6e0d _cg_png_read_info + 33 8 ImageIO 0x300ef62f copyImageBlockSetPNG + 1123 9 ImageIO 0x300eec4b ImageProviderCopyImageBlockSetCallback + 539 10 CoreGraphics 0x2f43577d CGImageProviderCopyImageBlockSetWithOptions + 137 11 CoreGraphics 0x2f43a145 subImageProviderCopyImageBlockSet + 305 12 CoreGraphics 0x2f43577d CGImageProviderCopyImageBlockSetWithOptions + 137 13 CoreGraphics 0x2f435433 img_blocks_create + 383 14 CoreGraphics 0x2f4286fd img_data_lock + 1053 15 CoreGraphics 0x2f427ae1 CGSImageDataLock + 89 16 libRIP.A.dylib 0x2f774da7 ripc_AcquireImage + 99 17 libRIP.A.dylib 0x2f774131 ripc_DrawImage + 601 18 CoreGraphics 0x2f4279f3 CGContextDelegateDrawImage + 51 19 CoreGraphics 0x2f427879 CGContextDrawImage + 285 20 WebCore 0x373120db WebCore::GraphicsContext::drawNativeImage(CGImage*, WebCore::FloatSize const&, WebCore::ColorSpace, WebCore::FloatRect const&, WebCore::FloatRect const&, float, WebCore::CompositeOperator, WebCore::BlendMode, WebCore::ImageOrientation) + 1127 21 WebCore 0x37310e79 WebCore::BitmapImage::draw(WebCore::GraphicsContext*, WebCore::FloatRect const&, WebCore::FloatRect const&, WebCore::ColorSpace, WebCore::CompositeOperator, WebCore::BlendMode, WebCore::RespectImageOrientationEnum) + 349 22 WebCore 0x3735d897 WebCore::BitmapImage::draw(WebCore::GraphicsContext*, WebCore::FloatRect const&, WebCore::FloatRect const&, WebCore::ColorSpace, WebCore::CompositeOperator, WebCore::BlendMode) + 31 23 WebCore 0x3735892f WebCore::Image::drawTiled(WebCore::GraphicsContext*, WebCore::FloatRect const&, WebCore::FloatPoint const&, WebCore::FloatSize const&, WebCore::ColorSpace, WebCore::CompositeOperator, WebCore::BlendMode) + 499 24 WebCore 0x37358735 WebCore::GraphicsContext::drawTiledImage(WebCore::Image*, WebCore::ColorSpace, WebCore::IntRect const&, WebCore::IntPoint const&, WebCore::IntSize const&, WebCore::CompositeOperator, bool, WebCore::BlendMode) + 193 25 WebCore 0x3728bc11 WebCore::RenderBoxModelObject::paintFillLayerExtended(WebCore::PaintInfo const&, WebCore::Color const&, WebCore::FillLayer const*, WebCore::LayoutRect const&, WebCore::BackgroundBleedAvoidance, WebCore::InlineFlowBox*, WebCore::LayoutSize const&, WebCore::CompositeOperator, WebCore::RenderObject*) + 3321 26 WebCore 0x3728addd WebCore::RenderBox::paintFillLayers(WebCore::PaintInfo const&, WebCore::Color const&, WebCore::FillLayer const*, WebCore::LayoutRect const&, WebCore::BackgroundBleedAvoidance, WebCore::CompositeOperator, WebCore::RenderObject*) + 449 27 WebCore 0x3728ab41 WebCore::RenderBox::paintBackground(WebCore::PaintInfo const&, WebCore::LayoutRect const&, WebCore::BackgroundBleedAvoidance) + 317 28 WebCore 0x37289ee5 WebCore::RenderBox::paintBoxDecorations(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 329 29 WebCore 0x3728806f WebCore::RenderBlock::paintObject(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 55 30 WebCore 0x37289c3f WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 187 31 WebCore 0x37288cc9 WebCore::RenderBlock::paintFloats(WebCore::PaintInfo&, WebCore::LayoutPoint const&, bool) + 305 32 WebCore 0x3728813d WebCore::RenderBlock::paintObject(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 261 33 WebCore 0x37289c3f WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 187 34 WebCore 0x37288cfb WebCore::RenderBlock::paintFloats(WebCore::PaintInfo&, WebCore::LayoutPoint const&, bool) + 355 35 WebCore 0x3728813d WebCore::RenderBlock::paintObject(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 261 36 WebCore 0x37289c3f WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&) + 187 37 WebCore 0x37288861 WebCore::RenderLayer::paintForegroundForFragmentsWithPhase(WebCore::PaintPhase, WTF::Vector<WebCore::LayerFragment, 1ul, WTF::CrashOnOverflow> const&, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*) + 269 38 WebCore 0x372886e7 WebCore::RenderLayer::paintForegroundForFragments(WTF::Vector<WebCore::LayerFragment, 1ul, WTF::CrashOnOverflow> const&, WebCore::GraphicsContext*, WebCore::GraphicsContext*, WebCore::LayoutRect const&, bool, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*, bool, bool) + 235 39 WebCore 0x37286435 WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 1585 40 WebCore 0x37285ca9 WebCore::RenderLayer::paintLayer(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 621 41 WebCore 0x372885d9 WebCore::RenderLayer::paintList(WTF::Vector<WebCore::RenderLayer*, 0ul, WTF::CrashOnOverflow>*, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 101 42 WebCore 0x3728647f WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 1659 43 WebCore 0x37285ca9 WebCore::RenderLayer::paintLayer(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 621 44 WebCore 0x372885d9 WebCore::RenderLayer::paintList(WTF::Vector<WebCore::RenderLayer*, 0ul, WTF::CrashOnOverflow>*, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 101 45 WebCore 0x3728647f WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 1659 46 WebCore 0x37285ca9 WebCore::RenderLayer::paintLayer(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int) + 621 47 WebCore 0x372859b3 WebCore::RenderLayer::paint(WebCore::GraphicsContext*, WebCore::LayoutRect const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, unsigned int) + 103 48 WebCore 0x3728541b WebCore::FrameView::paintContents(WebCore::GraphicsContext*, WebCore::IntRect const&) + 499 49 WebKit 0x37c4578d -[WebFrame(WebInternal) _drawRect:contentsOnly:] + 357 50 WebKit 0x37c455b9 -[WebHTMLView drawSingleRect:] + 137 51 WebKit 0x37c454db -[WebHTMLView drawRect:] + 43 52 WebCore 0x37284d93 -[WAKView _drawRect:context:lockFocus:] + 275 53 WebCore 0x37284ec7 -[WAKView _drawRect:context:lockFocus:] + 583 54 WebCore 0x37284ec7 -[WAKView _drawRect:context:lockFocus:] + 583 55 WebCore 0x37284ec7 -[WAKView _drawRect:context:lockFocus:] + 583 56 WebCore 0x37284ec7 -[WAKView _drawRect:context:lockFocus:] + 583 57 WebCore 0x37284c47 -[WAKView displayRect:] + 59 58 WebCore 0x37284c03 -[WAKWindow displayRect:] + 55 59 WebCore 0x37284b49 WebCore::TileCache::drawWindowContent(TileLayer*, CGContext*, CGRect) + 673 60 WebCore 0x37284525 WebCore::TileCache::drawLayer(TileLayer*, CGContext*) + 505 61 QuartzCore 0x317d3813 CABackingStoreUpdate_ + 1859 62 QuartzCore 0x318ad735 ___ZN2CA5Layer8display_Ev_block_invoke + 53 63 QuartzCore 0x317d30c3 x_blame_allocations + 83 64 QuartzCore 0x317d2d77 CA::Layer::display_() + 1119 65 QuartzCore 0x317b6969 CA::Layer::display_if_needed(CA::Transaction*) + 209 66 QuartzCore 0x317b6601 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 25 67 QuartzCore 0x317b600d CA::Context::commit_transaction(CA::Transaction*) + 229 68 QuartzCore 0x317b5e1f CA::Transaction::commit() + 315 69 UIKit 0x31d973c9 _UIWindowUpdateVisibleContextOrder + 209 70 UIKit 0x31d9729d +[UIWindow _prepareWindowsPassingTestForAppResume:] + 13 71 UIKit 0x31db0ac5 -[UIApplication _updateSnapshotAndStateRestorationArchiveForBackgroundEvent:saveState:exitIfCouldNotRestoreState:] + 201 72 UIKit 0x31db0d81 -[UIApplication _replyToBackgroundFetchRequestWithResult:remoteNotificationToken:sequenceNumber:updateApplicationSnapshot:] + 105 73 UIKit 0x31db138d __61-[UIApplication _handleOpportunisticFetchWithSequenceNumber:]_block_invoke + 37 74 MyApp 0x001456b7 -[List fetched:error:withBackgroundFetchCompletionHandler:] (List.m:421) 75 MyApp 0x00144f87 __71-[List fetchFromServerWithBackgroundFetchCompletionHandler:]_block_invoke (List.m:292) 76 MyApp 0x0021ed07 APICompletionBlock_block_invoke_6 (APIRequest.m:305) 77 libdispatch.dylib 0x39b8c103 _dispatch_call_block_and_release + 11 78 libdispatch.dylib 0x39b8c0ef _dispatch_client_callout + 23 79 libdispatch.dylib 0x39b8e9a9 _dispatch_main_queue_callback_4CF + 269 80 CoreFoundation 0x2f3785b9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 81 CoreFoundation 0x2f376e85 __CFRunLoopRun + 1309 82 CoreFoundation 0x2f2e1541 CFRunLoopRunSpecific + 525 83 CoreFoundation 0x2f2e1323 CFRunLoopRunInMode + 107 84 GraphicsServices 0x340182eb GSEventRunModal + 139 85 UIKit 0x31b981e5 UIApplicationMain + 1137 86 MyApp 0x0009f77f main (main.m:14) 

将应用程序保留在后台时,会将当前视图的快照保存到内存中,以便在双击主页button时显示该快照。 使用iOS7后台刷新function( (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler ),完成执行后必须执行completionHandler函数获取请求。

该函数的执行也会触发对UI的更新 – [UIApplication _updateSnapshotAndStateRestorationArchiveForBackgroundEvent:saveState:exitIfCouldNotRestoreState:] ,在你的情况下它会触发从后台线程计算UIWebView的框架。 UIWebView只能从UIThread更新,所以为了克服这个崩溃,我build议在主线程上执行completionHandler来执行:

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void(^)(UIBackgroundFetchResult result))completionHandler
 {
     void(^ safeHandler)(UIBackgroundFetchResult)= ^(UIBackgroundFetchResult结果){
         dispatch_async(dispatch_get_main_queue(),^ {
             completionHandler(结果);
         });
     };
     [someInstance doSomethingInBackground:userInfo withHandler:safeHandler];
 }

而且你将不必再担心从哪里调用completionHandler (现在是safeHandler )。