2010-08-20 75 views
3

sizeWithFont在多线程坠毁,这是调试信息:sizeWithFont in MultiThread Crash!

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

当然,我编辑的标签,但你真的需要解释更加协调一致得到任何回答。 – Aaron 2010-08-20 03:08:44

+1

这些护目镜对于这个问题什么都不做! AHHHHH MY EYES !!!!他们烧了! – 2010-08-20 03:16:07

回答

4

通常,您不应该从单独的线程调用UIKit方法[1]。如果你正在上锁,这并不重要,这是一个不起眼的问题。

当您使用多线程应用程序时,您需要确保触及任何UIKit对象的任何代码都在主线程上执行。 withObject:waitUntilDone:方法,该方法调用主线程上的给定的选择:

http://developer.apple.com/iphone/library/documentation/cocoa/reference/foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone

或者在MonoTouch的:这是通过使用所述performSelectorOnMainThread实现foo.InvokeOnMainThread(委托{your_code_here});

[1]对于iOS 4.0,对于少数几种API,这个规则是放松的。

+0

包括MonoTouch版本对我很有帮助,谢谢。 – vlad259 2011-01-19 14:06:30

4
  • 格式出现,请。

  • 通过在对象周围放置随机锁定“解决”多线程问题永远不是正确的答案。永远不会。多线程需要对应用程序进行系统设计。

  • 如果锁确实能够“解决”问题,显示您锁定的内容以及评估情况的关键点。

  • 还有一些症状会有帮助。代码,特别是。代码在你的问题是非常有用的。

鉴于缺乏证据,我敢打赌,你在一个线程上突变字符串,同时试图抓住另一个线程的大小。或者该对象正在一个线程上释放,同时仍然使用另一个线程。或者你正在操作一个不是线程安全的辅助线程中的对象。

+0

我不知道Cocoa对象,堆栈中引用的ICU对象当然可能不会以这种方式从多个线程中使用。另一个答案似乎也支持了这一点。我认为你需要弄清楚如何不一次从两个线程调用这个对象。 – 2010-08-20 19:18:33

0

我想performSelectorOnMainThread:withObject:waitUntilDone:是正确的,

之前,我用一个操作来计算文本大小, 并使用waitUntilAllOperationsAreFinished在主线程等待操作的回归,
但是,如果我还使用performSelectorOnMainThread:withObject:waitUntilDone在操作,并且waitUntilDone参数设置为Yes(因为我需要的结果)
主线程将被stucked

所以现在我删除waitUntilAllOperationsAreFinished,并使用asynchrono我们反对,以确保 操作将无法启动,直到前面的人拦

    [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;