Why does my app crash when backgrounding when using [NSAttributedString initWithData]

匿名 (未验证) 提交于 2019-12-03 01:17:01

问题:

I have a viewController that manages a UICollectionView. I have a helper method that is called from cellForItemAtIndexPath that provides an NSAttributedString for a label in the cell. The helper method formats an NSAttributedString from an html string. The app will crash when moving to the background, but only if the indexPath.item is greater than 1. In other words, I can exit the app without crashing from the first or second cell, but crash consistently on the third, forth, ... cell.

Here are my helper method and stack trace. Any idea why I am crashing on exiting the app?

#pragma mark - === Utility Methods === -  - (NSAttributedString *)stepDescriptionStringForIndexPath:(NSIndexPath *)indexPath {      NSString *headerString;     NSString *htmlString;     NSString *categoryString = [NSString stringWithFormat:@"Category: %@", self.knot.category.categoryName];     NSString *abokString = [NSString stringWithFormat:@"ABOK #: %@", self.knot.abokNumber];     NSMutableString *activitiesString = [NSMutableString stringWithCapacity:10];     [activitiesString appendString:@"Activities: "];      // build a string of activities to append to the description html     NSArray *activities = [self.knot.activities allObjects];     if ([activities count] > 0) {         int counter = 1;         for (Activity *activity in activities) {             [activitiesString appendString:activity.activityName];             if (counter < [activities count]) {                 [activitiesString appendString:@", "];             }             counter ++;         }     }      // build an HTML string by concatinating the activities to the step description     // and add the header string     if(indexPath.item > 0){         Step *step = (Step *)self.steps[indexPath.item - 1];         headerString = [NSString stringWithFormat:@"Step %ld of %lu", (long)indexPath.item, (unsigned long)[self.steps count]];         htmlString =[NSString stringWithFormat:@"<p>%@</p>%@", headerString, step.stepDescription];     } else {         headerString = @"Overview";         htmlString = [NSString stringWithFormat:@"<p>%@</p>%@<p>%@</br>%@</br>%@</p>", headerString, self.knot.knotDescription, categoryString, abokString, activitiesString];      }      // convert the html string to an attributed string     NSMutableAttributedString *attrStringFromHTML = [[NSMutableAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding]                                                                                             options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,                                                                                                       NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]}                                                                                  documentAttributes:nil                                                                                               error:nil];      // set the font for the body     NSRange totalRange;     totalRange.location = 0;     totalRange.length = attrStringFromHTML.length;     [attrStringFromHTML addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16] range:totalRange];      // set the font for the header     NSString *temp = [attrStringFromHTML string];      NSRange headerRange = [temp rangeOfString:headerString];     NSRange categoryRange = [temp rangeOfString:categoryString];     NSRange abokRange = [temp rangeOfString:abokString];     NSRange activitiesRange = [temp rangeOfString:activitiesString];      [attrStringFromHTML addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:18] range:headerRange];     //set the font for the activities paragraph     if(indexPath.item == 1){          [attrStringFromHTML addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:categoryRange];         [attrStringFromHTML addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:abokRange];         [attrStringFromHTML addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:activitiesRange];       }     return attrStringFromHTML; } 
 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unexpected start state' *** First throw call stack: (     0   CoreFoundation                      0x00000001131aad85 __exceptionPreprocess + 165     1   libobjc.A.dylib                     0x0000000112c1edeb objc_exception_throw + 48     2   CoreFoundation                      0x00000001131aabea +[NSException raise:format:arguments:] + 106     3   Foundation                          0x0000000110b96e1e -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 169     4   UIKit                               0x00000001113a7d4e _prepareForCAFlush + 256     5   UIKit                               0x00000001113b40b4 _beforeCACommitHandler + 12     6   CoreFoundation                      0x00000001130cfc37 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23     7   CoreFoundation                      0x00000001130cfba7 __CFRunLoopDoObservers + 391     8   CoreFoundation                      0x00000001130c511c CFRunLoopRunSpecific + 524     9   UIFoundation                        0x000000011a697a7a -[NSHTMLReader _loadUsingWebKit] + 2093     10  UIFoundation                        0x000000011a698e74 -[NSHTMLReader attributedString] + 22     11  UIFoundation                        0x000000011a6323c0 _NSReadAttributedStringFromURLOrData + 5623     12  UIFoundation                        0x000000011a630d34 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 115     13  WhatKnotToDo                        0x000000010e84d3ac -[CSC_iPad_KnotDetailViewController stepDescriptionStringForIndexPath:] + 2476     14  WhatKnotToDo                        0x000000010e84c31d -[CSC_iPad_KnotDetailViewController collectionView:cellForItemAtIndexPath:] + 477     15  UIKit                               0x0000000111bff08f -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:] + 483     16  UIKit                               0x0000000111c02d96 -[UICollectionView _updateVisibleCellsNow:] + 4988     17  UIKit                               0x0000000111c07575 -[UICollectionView layoutSubviews] + 258     18  UIKit                               0x0000000111442980 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 703     19  QuartzCore                          0x0000000112af6c00 -[CALayer layoutSublayers] + 146     20  QuartzCore                          0x0000000112aeb08e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366     21  QuartzCore                          0x0000000112aeaf0c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24     22  QuartzCore                          0x0000000112adf3c9 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277     23  QuartzCore                          0x0000000112b0d086 _ZN2CA11Transaction6commitEv + 486     24  UIKit                               0x0000000111394a0b __65-[UIApplication _beginSnapshotSessionForScene:withSnapshotBlock:]_block_invoke2222 + 601     25  UIKit                               0x0000000111395201 __65-[UIApplication _performSnapshotsWithAction:forScene:completion:]_block_invoke2243 + 131     26  FrontBoardServices                  0x00000001153e3039 -[FBSSceneSnapshotAction _finishAllRequests] + 65     27  FrontBoardServices                  0x00000001153e2de3 -[FBSSceneSnapshotAction executeRequestsWithHandler:completionHandler:expirationHandler:] + 218     28  UIKit                               0x0000000111395024 __65-[UIApplication _performSnapshotsWithAction:forScene:completion:]_block_invoke + 305     29  UIKit                               0x0000000111394592 -[UIApplication _beginSnapshotSessionForScene:withSnapshotBlock:] + 1138     30  UIKit                               0x0000000111394eb2 -[UIApplication _performSnapshotsWithAction:forScene:completion:] + 629     31  UIKit                               0x0000000111394bbc -[UIApplication _handleSnapshotAction:forScene:completion:] + 153     32  UIKit                               0x0000000111390a8f __102-[UIApplication _handleApplicationDeactivationWithScene:shouldForceExit:transitionContext:completion:]_block_invoke1993 + 290     33  UIKit                               0x0000000111390657 __102-[UIApplication _handleApplicationDeactivationWithScene:shouldForceExit:transitionContext:completion:]_block_invoke1979 + 1258     34  UIKit                               0x0000000111393f62 _runAfterCACommitDeferredBlocks + 317     35  UIKit                               0x00000001113a7e4c _cleanUpAfterCAFlushAndRunDeferredBlocks + 95     36  UIKit                               0x00000001113b4147 _afterCACommitHandler + 90     37  CoreFoundation                      0x00000001130cfc37 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23     38  CoreFoundation                      0x00000001130cfba7 __CFRunLoopDoObservers + 391     39  CoreFoundation                      0x00000001130c57fb __CFRunLoopRun + 1147     40  CoreFoundation                      0x00000001130c50f8 CFRunLoopRunSpecific + 488     41  GraphicsServices                    0x0000000115203ad2 GSEventRunModal + 161     42  UIKit                               0x0000000111387f09 UIApplicationMain + 171     43  WhatKnotToDo                        0x000000010e820b7f main + 111     44  libdyld.dylib                       0x000000011396592d start + 1     45  ???                                 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException  

回答1:

I've come across this issue too, after a few hours, i've found a solution for this one.

You'll just need to wrap the code for converting the NSAttributedString into dispatch_async.

For example:

   DispatchQueue.MainQueue.DispatchAsync(() =>         {             var encodingData = ((NSString)html).Encode(NSStringEncoding.Unicode, true);             NSAttributedString data = new NSAttributedString(             encodingData,             new NSAttributedStringDocumentAttributes()             {                 DocumentType = NSDocumentType.HTML,              }, ref error);         }); 

I'm using Xamarin, so these are C# code, but i believe they're similar in Swift and Obj C.

Look like when the system is making transition between pages (view controller), it will try to prevent any heavy task running on UI Thread. Which cause this issue.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!