2

我想在 UITextview 中写一些日志文本。例如:加载 x 图像,创建 y 对象等。我的问题是:插入一行后 UITextView 不刷新。我认为当插入结束时,所有新文本都会同时显示。

append = [@"" stringByAppendingFormat:@"\n%@ file is dowloading...", refreshName]
logTextView.text = [logTextView.text stringByAppendingString: append];

下载后我保存文件并

append = [@"" stringByAppendingFormat:@"\n%@ file saved", refreshName];
logTextView.text = [logTextView.text stringByAppendingString: append];

我试过

[logTextView setNeedsDisplay]

或者

[logTextView performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];

但它没有用:(

会议将是:

  1. 在 textview 中插入新行(下载)
  2. 显示此文本
  3. 下载文件(几秒钟)
  4. 在 UITextView 中插入新行(下载完成)
  5. 显示文本

它发生的是:

  1. 下载文件(几秒钟)
  2. UITextView 显示行(下载ig,下载完成)
4

1 回答 1

1

文本只会在下一次通过主线程的 runloop 更新。如果您在主循环上有一个长时间运行的任务,并且它一直在写入 textView,那么在您的任务结束之前不会显示任何内容。

我可以想出几种方法来解决这个问题:

  • 在普通调度队列上运行大任务,并使用 dispatch_async(dispatch_get_main_queue(), append this new text) 向 textView 发送消息;这个想法是您的任务在辅助线程上执行(因此它不能直接向 UI 发送消息),而是通过向主队列发送短块来更新 UI。

  • 将您的大任务分解成块,每个块都可以由一个方法启动。在这种情况下,您在主队列中执行第一个,然后使用更新的 UITextView 文本向主队列分派一个块,然后执行下一个工作块。那是:

    dispatch_async(dispatch_get_main_queue(), ^ { update textView text; [self doTask1:maybeSomeDictionary]; }

当 doTask1 完成时,它调度下一个块:

dispatch_async(dispatch_get_main_queue(), ^
{
    update textView text again;
    [self doTask2:maybeSomeDictionary];
}

当最后的任务完成时,你就完成了。

于 2012-08-28T12:54:04.293 回答