sizeWithFont 不是线程安全。

时间:2023-03-09 00:58:47
sizeWithFont 不是线程安全。

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

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

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

    dispatch_async(queue, ^{

        NSString *string = @"My string";
CGSize size = [string sizeWithFont:[UIFont boldSystemFontOfSize:]];
});
} for (int i = ; i < ; i++) { NSString *string = @"My string";
CGSize size = [string sizeWithFont:[UIFont boldSystemFontOfSize:]];
} dispatch_release(queue);

错误代码:

WebCore`WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>):
。。。
0x2b635d8: jne 0x2b635f1 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) +
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 $, (%ebx)
。。。0x2b63674: je 0x2b63696 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) +
。。。
0x2b6367f: je 0x2b63686 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) +
0x2b63681: decl %ecx
0x2b63682: movl %ecx, (%eax)
0x2b63684: jmp 0x2b63693 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) +
0x2b63686: addl $-, %eax
0x2b63689: je 0x2b63693 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) +
0x2b6368b: movl (%eax), %ecx
。。。
0x2b63698: testl %ecx, %ecx
0x2b6369a: je 0x2b636a4 ; WebCore::FontFallbackList::invalidate(WTF::PassRefPtr<WebCore::FontSelector>) +
0x2b6369c: movl (%ecx), %eax
。。。
0x2b636a7: calll 0x2b5b740 ; WebCore::fontCache()
0x2b636ac: movl %eax, (%esp)
0x2b636af: calll 0x2b5cce0 ; WebCore::FontCache::generation()
。。。
0x2b636bf: ret

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

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

参考:

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