sizeWithFont在多线程中崩溃,这是调试信息:
1 0x00a0df8e in icu::RuleBasedBreakIterator::handleNext
2 0x00a0daff in icu::RuleBasedBreakIterator::next
3 0x00a0d174 in icu::RuleBasedBreakIterator::following
4 0x35879719 in WebCore::nextBreakablePosition
5 0x3587842a in -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:measureOnly:]
6 0x35877da3 in -[NSString(WebStringDrawing) _web_sizeInRect:withFont:ellipsis:lineSpacing:]
7 0x3090d238 in -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:lineSpacing:]
8 0x3090cee3 in -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:]
现在我通过使用NSLock对象来解决错误,在使用此函数之前我将锁定此对象,然后解锁它
但我认为必须有更好的解决方案!
我发现这个错误只出现在两个线程上这个函数的NSString对象都是多行文本
答案 0 :(得分:4)
请格式化。
通过在对象周围放置随机锁来“解决”多线程问题永远不是正确的答案。永远不会。多线程需要系统设计您的应用程序。
如果锁定确实“修复”了问题,则显示您锁定的内容以及评估情况的关键。
更多症状会有所帮助。特别是代码。您的问题中的代码非常有用。
鉴于缺乏证据,我打赌你在尝试抓住另一个线程的大小时,在一个线程上改变一个字符串。或者在一个线程上释放对象,同时仍然使用另一个线程。或者您正在操作非线程安全的辅助线程中的对象。
答案 1 :(得分:4)
通常,您不应该从单独的线程调用UIKit方法[1]。如果你正在拿锁,这没关系,这是一个非首发。
当您使用多线程应用程序时,您需要确保触及任何UIKit对象的任何代码都在主线程上执行。这是通过使用performSelectorOnMainThread:withObject:waitUntilDone:方法实现的,该方法在主线程上调用给定的选择器:
或者在MonoTouch中:foo.InvokeOnMainThread(委托{your_code_here});
[1]在iOS 4.0中,规则适用于少数API。
答案 2 :(得分:0)
我认为performSelectorOnMainThread:withObject:waitUntilDone:是正确的,
之前,我使用一个操作来计算文字大小,
并在主线程中使用waitUntilAllOperationsAreFinished等待操作的返回,
但是如果我在操作中也使用performSelectorOnMainThread:withObject:waitUntilDone,并将waitUntilDone参数设置为Yes(因为我需要结果)
主线程将被卡住
所以现在我删除了waitUntilAllOperationsAreFinished,并使用异步对象来确保 在前一个停止之前,操作不会开始
[md removeAllObjects];
[md setObject:subString forKey:@"text"];
[md setObject:[NSNumber numberWithInt:view_w ] forKey:@"width"];
[md setObject:[NSNumber numberWithInt:height_left + font_h ] forKey:@"height"];
[self performSelectorOnMainThread:
@selector(calculateTextRegion:)
withObject:md
waitUntilDone:YES];
CGSize stringSize = textRegion;