主线程上的同步时间会导致主线程阻塞。这是UI延迟的原因吗?如果我在主线程上执行异步、耗时的操作,这会影响主线程上UI的流吗?同样,耗时的操作必须放在子线程异步操作中.
发布于 2019-05-21 15:44:45
你能举个例子说明你有问题的一些操作吗?
如果主线程忙着做其他事情而不是UI发布的事情,那么是的,您可能会经历一个缓慢的或不可用的UI。
通常情况下,应该在后台线程上执行耗时或同步的操作,以避免出现此问题。但是,请注意,UI/UIKit相关操作必须在主线程上执行,否则应用程序可能会崩溃。
发布于 2019-05-21 15:45:00
如果您在主线程上并向异步线程分派一些东西,则除非该线程正在消耗设备上的所有资源,否则它不会对UI产生影响。
但是,当您完成异步线程并使用异步操作的结果更新UI时,您将得到什么。如果忘记将UI更新移到主线程上,UI可能会在某个随机时间间隔更新,或者根本不会更新。这就是大多数人在进行异步操作时得到的好处。
发布于 2019-05-21 17:14:54
通常,异步地向后台队列分配某些内容不会对UI产生实质性影响。这正是我们这么做的原因,以尽量减少对UI的影响。
如果你看到了滞后,这可能会发生在:
在编辑中,您提供了一些示例:
当您将块分派回主线程时,您不希望包含这些耗时的任务,否则会对UX产生不利影响。在发送到主队列之前,在后台线程上执行这些耗时的任务。
[NSThread detachNewThreadSelector:@selector(asyncMain) toTarget:self withObject:nil];
- (void)asyncMain {
dispatch_queue_t queue = dispatch_get_main_queue();
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // Simulated time-consuming operation
NSLog(@"1---%@",[NSThread currentThread]); // still on the background thread
}
dispatch_async(queue, ^{
self.testImage=[UIImage imageNamed:xxx];//Execute code now
});
}
并且没有理由同步地将更新发送回主队列。异步分派这些更新,为什么后台线程要等待UI更新完成?
就我个人而言,我建议取消detachNewThreadSelector
,坚持使用GCD (就像您的第三个例子):
- (void)someTaskAndUpdateUI {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // Simulated time-consuming operation
NSLog(@"1---%@",[NSThread currentThread]); // but on background queue
}
dispatch_async(dispatch_get_main_queue(), ^{
self.testImage=[UIImage imageNamed:xxx];//Execute code now
});
});
}
异步地将其分派到主线程vs的事实是不重要的。问题不在于如何分配到主队列,而在于您分派了什么。分派给主线程的代码有一些慢任务,这意味着主线程在发生慢任务时不能做任何其他事情。这就是对UI产生不利影响的原因。
因此,解决方案与上面一样,您希望在分派到主队列之前执行这些耗时的任务。虽然从主线程的角度来看,同步或异步分派并不重要,但我们通常倾向于异步进行。同样,为什么后台线程需要坐在那里等待UI更新完成。
对,是这样。我建议您使用第三种模式,并从代码中完全删除detachNewThreadSelector
。坚持GCD。
https://stackoverflow.com/questions/56241811
复制相似问题