【发布时间】:2019-11-17 14:28:20
【问题描述】:
我以前从未使用过后台线程。我目前在主线程上运行一个耗时的计算,它将数据输出附加到 TERecord。我的工作流程基本上是:
运行漫长的过程... 更新界面… 运行漫长的过程... 更新界面… 等等。
在代码产生(字符串)输出的几个地方,我通过调用此处显示的“addToRecord”方法来更新 UI:
-(void)addToRecord:(NSString*)passedStr:(BOOL)updateUI
{
NSRange endRange;
// add the passed text...
endRange.location = [[theOutputView textStorage] length];
endRange.length = 0;
[theOutputView replaceCharactersInRange:endRange withString:passedStr];
if(updateUI) // immediate GUI update needed...
{
// scroll window contents to BOTTOM of page...
endRange = NSMakeRange([[theOutputView string] length],0);
[theOutputView scrollRangeToVisible:endRange];
[theOutputView display];
}
}
当然,虽然它完成了这项工作,但我的整个 UI 仍然没有响应,直到该过程完成。我知道我应该在我以前从未使用过的后台线程上做繁重的工作。我在创建如下后台线程时发现了部分问题:
-(IBAction)readUserInput:(id)sender
{
// irrelevant code snipped for brevity
if([self checkForErrors] == NO)
{
[runButton setEnabled:NO];
[self performSelectorInBackground:@selector(runWorkThread) withObject:nil];
}
}
-(void)runWorkThread
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
[self runLongProcess];
[pool drain];
}
但是我只是不明白每次代码遇到我的'addToRecord'方法时如何调用主线程,那么如何将控制权返回给后台线程? 另一种可能性可能是从我的“addToRecord”方法中删除 updateUI 代码,并让主线程每隔一秒左右在计时器上调用此代码?
任何建议和示例代码将不胜感激。谢谢!
【问题讨论】:
-
你好,只是想和你澄清一下你的问题,你想在
runLongProcess完成后,你想填充一些东西还是通知在主线程上调用-(void)addToRecord:(NSString*)passedStr:(BOOL)updateUI? -
@HSG。当我在主线程上运行长进程时,它在进程结束之前调用了大约十几次“addToRecord”。每次这都会向 NSTextView 绘制额外的文本并以连续滚动动作更新 UI。我想从我的后台线程中删除此方法的“updateUI”部分,让它只是将附加文本附加到 TERecord 并以某种方式让主线程更新 UI 并显示它。如果在后台进程运行时(几分钟)我无法更新 UI 至少 2-3 次,空白文本视图会使其看起来像应用程序已停止。
标签: objective-c multithreading user-interface