目标c只能从主线程调用
Posted
技术标签:
【中文标题】目标c只能从主线程调用【英文标题】:objective c can only be called from main thread 【发布时间】:2015-12-23 19:48:53 【问题描述】:我正在尝试从 javascript 使用的回调方法调用委托。但是当我从回调执行委托而不是事件触发时,我收到了错误"Can only be called from main thread"
。
注意:错误在代码的最后一行。
这是代码的样子
RCT_EXPORT_METHOD(setBold)
if(_bold == NO)
_bold = YES;
else if (_bold == YES)
_bold = NO;
else
_bold = NO;
if(_textV!=nil)
_delCalled = YES;
[self textViewDidChangeSelection:_textV];
-(void)textViewDidChangeSelection:(UITextView *)textView
_textV = textView;
_selectedText = [textView.text substringWithRange:textView.selectedRange];
_rangeStart = textView.selectedRange.location;
_rangeEnd = textView.selectedRange.length;
if(_delCalled == YES)
[self applyBold:textView];
_delCalled = NO;
NSDictionary *event = @
@"target": textView.reactTag,
@"highlights": @
@"text": textView.text,
@"range": @(textView.selectedRange.length),
@"cursorPosition": @(textView.selectedRange.location),
@"eventType": @"textViewDidChangeSelection",
;
[self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event];
-(void)applyBold:(UITextView *)textView
NSMutableAttributedString *formatString;
UIFont* boldFont;
NSString *selectedText = _selectedText;
_rangeStart -=1;
if(_rangeEnd == 0)
_rangeEnd = 1;
else
_rangeStart +=1;
NSRange range = NSMakeRange(_rangeStart, _rangeEnd);
if (_bold==YES)
boldFont= [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
else
boldFont= [UIFont systemFontOfSize:textView.font.pointSize];
NSAttributedString *lem = textView.attributedText;
NSMutableAttributedString *textViewText = [[NSMutableAttributedString alloc]initWithAttributedString:textView.attributedText];
NSDictionary *boldAttr = [NSDictionary dictionaryWithObject:boldFont forKey:NSFontAttributeName];
formatString = [[NSMutableAttributedString alloc]initWithString:selectedText attributes:boldAttr];
if(![selectedText isEqual:@""] || ![selectedText isEqual:@" "])
[textViewText replaceCharactersInRange:range withAttributedString:formatString];
//this is where the error happens
textView.attributedText = textViewText;
【问题讨论】:
【参考方案1】:在 ios 中,任何更新 UI 的方法都必须在主线程上调用。 iOS UIKit 不是线程安全的。因此,解决方案是将代码放在主线程上,像这样
dispatch_async( dispatch_get_main_queue(), ^
textView.attributedText = textViewText;
);
【讨论】:
【参考方案2】:将产生错误的行包含在主队列的 dispatch_async 中
dispatch_async(dispatch_get_main_queue(), ^
...
);
【讨论】:
谢谢你修复它。以上是关于目标c只能从主线程调用的主要内容,如果未能解决你的问题,请参考以下文章
GMSThreadException' 原因:'API 方法必须从主线程调用'