sizeWithFont 不是線程安全。

 在ios開發中常用用sizeWithFont 方法來計算UILabel 的frame, 例如動態計算UITableViewCell 的高度,在主線程處理沒有問題,可是在子線程用此方法來計算就會出現Crash,由於 UIStringDrawing 中的方法不是線程安全的。如下代碼在ios6 模擬器中測試過:ios

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放在主線程中使用。async

stackoverflow上也有其餘計算方法,本人沒試過。測試

參考:ui

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

相關文章
相關標籤/搜索