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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With