UIKit字符串绘制方法中的错误?

Sno*_*man 4 iphone objective-c ios

为了复制我在我的应用程序中遇到的崩溃,我不得不创建一个稍微夸张的重复率的示例,这可能不实用,但是它可以准确地演示我的应用程序中发生了什么.在后台线程上使用时绘制NSString时NSOperations,有时会在崩溃之前对堆栈跟踪上的最后一次调用发生崩溃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];
}
Run Code Online (Sandbox Code Playgroud)

您可以使用上面的代码轻松复制此崩溃.任何人都可以了解这次事故的性质,以及为什么会发生这种情况?(这个问题的解决方案是设置[queue setMaxConcurrentOperations:1];)

tc.*_*tc. 5

这似乎是iOS 5.x中的回归:它发生在5.0和5.1模拟器和5.1设备上,但不在4.3模拟器或4.3.2设备上.

它也特别是字符串绘图似乎被打破 - 如果您所做的只是字符串绘制(避免创建/销毁上下文的开销),崩溃几乎立即发生:

-(void)threadFunc:(UIFont *)font {
  @autoreleasepool {
    NSString *string = @" ";
    CGRect r = {{0,0},{50,50}};
    UIGraphicsBeginImageContextWithOptions(r.size, YES, 0);
    for(;;) {
      @autoreleasepool {
        [string drawAtPoint:r.origin withFont:font];
      }
    }
    UIGraphicsEndImageContext();
  }
}

-(void)startThreads
{
  UIFont * font = [UIFont systemFontOfSize:12];
  for (int i = 2; i--;)
  {
    [NSThread detachNewThreadSelector:@selector(threadFunc:) toTarget:self withObject:font];
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:仅在多核环境(即双核设备或模拟器,假设多核Mac)中"几乎是即时".否则,崩溃需要大约10-20分钟.我没有双核iOS 4.x设备(唯一的可能性似乎是iPad 2),但单核设备在一个多小时后没有崩溃.

我已经向Apple提出了一个错误,如果它影响到你,我会鼓励你这样做.