为什么在使用[NSAttributedString initWithData]的背景下我的应用程序崩溃 [英] Why does my app crash when backgrounding when using [NSAttributedString initWithData]
问题描述
我有一个管理UICollectionView的viewController.我有一个从cellForItemAtIndexPath调用的辅助方法,该方法为单元格中的标签提供了NSAttributedString. helper方法从html字符串格式化NSAttributedString.移至后台时,该应用程序将崩溃,但前提是indexPath.item大于1.换句话说,我可以退出该应用程序而不会从第一个或第二个单元格崩溃,但是在第三个,第二个单元格上始终崩溃. ..单元格.
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.
您只需要包装用于将NSAttributedString
转换为dispatch_async的代码即可.
You'll just need to wrap the code for converting the NSAttributedString
into dispatch_async.
例如:
DispatchQueue.MainQueue.DispatchAsync(() =>
{
var encodingData = ((NSString)html).Encode(NSStringEncoding.Unicode, true);
NSAttributedString data = new NSAttributedString(
encodingData,
new NSAttributedStringDocumentAttributes()
{
DocumentType = NSDocumentType.HTML,
}, ref error);
});
我正在使用Xamarin,所以它们是C#代码,但我相信它们在Swift和Obj C中是相似的.
I'm using Xamarin, so these are C# code, but i believe they're similar in Swift and Obj C.
就像系统在页面之间进行过渡(视图控制器)时,它将尝试防止在UI Thread上运行任何繁重的任务.造成此问题的原因.
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.
这篇关于为什么在使用[NSAttributedString initWithData]的背景下我的应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!