In order to replicate a crash I was having in my application, I had to create a sample with a slightly exaggerated repeat rate that might not be practical, but one that demonstrates exactly what was happening in my app. When drawing an NSString on a background thread using NSOperations, there is sometimes a crash with the last call on the stack trace before the crash being WebCore::FontFallbackList::~FontFallBackList().
- (void)viewDidLoad
{
queue = [[NSOperationQueue alloc] init];
[NSTimer scheduledTimerWithTimeInterval:0.0001 target:self selector:@selector(timerDidFire:) userInfo:nil repeats:YES];
}
-(void)timerDidFire:(NSTimer*)timer
{
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
CGRect rect = CGRectMake(0, 0, 50, 50);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(rect.size.width, rect.size.height), YES, 0.0);
NSString *string = @"Sd";
[string drawInRect:rect withFont:[UIFont boldSystemFontOfSize:12] lineBreakMode:UILineBreakModeTailTruncation];
UIGraphicsEndImageContext();
}];
[queue addOperation:op];
}
You can easily replicate this crash with the code above. Anyone have any insight as to the nature of this crash, and why it might be happening?
(the solution to this problem is setting [queue setMaxConcurrentOperations:1];)
This appears to be a regression in iOS 5.x: It happens on the 5.0 and 5.1 simulators and on a 5.1 device, but not on the 4.3 simulator or a 4.3.2 device.
It’s also specifically the string drawing that seems to be broken — if all you do is string-drawing (avoiding the overhead of creating/destroying contexts), the crash happens nearly instantly:
EDIT: It is “nearly instant” only in multi-core environments (i.e. a dual-core device or the simulator, assuming a multi-core Mac). Otherwise, it takes on the order of 10-20 minutes to crash. I don’t have a dual-core iOS 4.x device (the only possibility appears to be the iPad 2), but the single-core devices haven’t crashed after over an hour.
I’ve raised a bug with Apple, and encourage you to do the same if it affects you.