I had a need to display HTML text inside my iOS app. I have decided I will use the built-in method on NSAttributedString
, initWithData:options:documentAttributes:error:
. The actual parsing works excellently, however, I seem to have come across a very odd bug, that only seems to manifest itself if I have the debugger attached.
The first time that this method is called, it takes barely under 1 second to run on my iPhone 5S running iOS 7.0.4, and about 1.5 seconds on an iPod Touch 5th generation. The quirk also manifests itself on the simulator, but it is significantly less noticeable, due to the sheer speed of the simulator.
Subsequent calls only take around 10-50ms, which is significantly faster than the initial call.
This doesn't appear to be related to caching of the input string, as I have tested it with multiple input strings in my 'real' application.
However, when I run the program without the debugger, it runs as expected, taking about 10-20ms, which is what I expect HTML parsing to take.
Here is the relevant section of code:
-(void) benchmarkMe:(id)sender {
NSData *data = [testString dataUsingEncoding:NSUTF8StringEncoding];
NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];
// So the complier doesn't keep complaining at me.
__attribute__((unused))
NSAttributedString *parsed = [[NSAttributedString alloc] initWithData:data
options:@{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)
}
documentAttributes:nil
error:nil];
NSTimeInterval endTime = [[NSDate date] timeIntervalSinceReferenceDate];
NSString *message = [NSString stringWithFormat:@"Took %lf seconds.", endTime - startTime];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Benchmark complete!"
message:message
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertView show];
}
Note: A fully working project demonstrating this bug is available here:
https://github.com/richardjrossiii/NSAttributedStringHTMLBug
Am I crazy? Is there something I'm missing here? 1 second is an awfully large amount of time when I'm trying to optimize my app for performance.
My current solution is to parse a 'dummy' string on application launch, but this seems like an incredibly hacky workaround.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…