sizeWithFont 不是线程安全。

 在ios开发中经常使用用sizeWithFont 方法来计算UILabel 的frame, 例如动态计算UITableViewCell 的高度,在主线程处理没有问题,但是在子线程用此方法来计算就会出现Crash,因为 UIStringDrawing 中的方法不是线程安全的。以下代码在ios6 模拟器中测试过:

dispatch_queue_t queue = dispatch_queue_create("com.queue", NULL);



for (int i = 0; i < 10000; i++) {



    dispatch_async(queue, ^{



        NSString *string = @"My string";

        CGSize size = [string sizeWithFont:[UIFont boldSystemFontOfSize:13]];

    });

}



for (int i = 0; i < 10000; i++) {



    NSString *string = @"My string";

    CGSize size = [string sizeWithFont:[UIFont boldSystemFontOfSize:13]];

}



dispatch_release(queue);

错误代码:

WebCore`WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>):

。。。

0x2b635d8:  jne    0x2b635f1                 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) + 65

0x2b635da:  calll  0x2b5b740                 ; WebCore::fontCache()

。。。

0x2b635ec:  calll  0x2b5c210                 ; WebCore::FontCache::releaseFontData(WebCore::SimpleFontData const*)

0x2b635f1:  incl   %ebx

。。。0x2b63620:  calll  0x364281a                 ; symbol stub for: WTF::fastFree(void*)

0x2b63625:  movl   $0, 4(%ebx)

。。。0x2b63674:  je     0x2b63696                 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) + 230

。。。

0x2b6367f:  je     0x2b63686                 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) + 214

0x2b63681:  decl   %ecx

0x2b63682:  movl   %ecx, (%eax)

0x2b63684:  jmp    0x2b63693                 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) + 227

0x2b63686:  addl   $-4, %eax

0x2b63689:  je     0x2b63693                 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) + 227

0x2b6368b:  movl   (%eax), %ecx

。。。

0x2b63698:  testl  %ecx, %ecx

0x2b6369a:  je     0x2b636a4                 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) + 244

0x2b6369c:  movl   (%ecx), %eax

。。。

0x2b636a7:  calll  0x2b5b740                 ; WebCore::fontCache()

0x2b636ac:  movl   %eax, (%esp)

0x2b636af:  calll  0x2b5cce0                 ; WebCore::FontCache::generation()

。。。

0x2b636bf:  ret    

所以,建议使用UIStringDrawing放在主线程中使用。

stackoverflow上也有其他计算方法,本人没试过。

参考:

http://stackoverflow.com/questions/12744558/uistringdrawing-methods-dont-seem-to-be-thread-safe-in-ios-6

你可能感兴趣的:(线程安全)