2017-06-17 65 views
0

我有一个后台线程的循环,其中我想告诉用户它的进度。UI性能税

所以,在这个循环中,我称之为

[self performSelectorOnMainThread:@selector(updateProgressBarto:) withObject:@(value) waitUntilDone:YES]; 

我把一些日志记录的循环之前和之后,并提出以下意见:

如果我能以上述行显示进度,我记录控制台显示:

2017-06-17 16:43:49.675 myApp[8523:551864] Start Import 
2017-06-17 16:43:59.119 myApp[8523:551864] Done Importing 

这是一个DELT一个大约9.5秒

没有进度条,它看起来像

2017-06-17 16:47:06.052 myApp[8611:556572] Start Import 
2017-06-17 16:47:12.776 myApp[8611:556572] Done Importing 

6.7秒

作为对比,如果循环是在后台运行取,有根本没有UI参与,日志显示:

2017-06-17 16:45:12.199 myApp[8523:553684] Start Import 
2017-06-17 16:45:13.084 myApp[8523:553684] Done Importing 

这是小于一秒

如果我设置

waitUntilDone:NO 

我得到的不良副作用,进度栏更新只有3次,而不是50 +倍。

技术问题:这是我/用户必须忍受的事情,还是有任何感知技巧来解决这个问题?

心理问题: 你/用户喜欢6秒不超过9秒反馈视觉反馈?

您的见解非常受欢迎。

+0

你是对的,你不应该等待。而且,最好使用GCD的'dispatch_async'而不是'performSelector'调用。但是,你的数字乞讨了为什么进度条更新需要花费那么多时间。但我们需要看看那里发生了什么,以便发表评论。简单的进度条更新应该在6秒内轻松更新超过50次。这里还有其他事情要做。 – Rob

回答

0

为什么不使用GDC做UI更新异步。应该有在后台线程和小延迟的UI非常小的开销:

dispatch_async(dispatch_get_main_queue(), ^{ 
     [self updateProgressBarto:@(value)]; 
    }); 

另外,也许你不需要更新每次迭代的UI,但只有每10或100

if !(i % 10) { 
    // update UI progress bar 
} 
+0

我喜欢这个技巧,因为progressBar可以动态更新。我会试一试,然后回到你身边(明天) – Sjakelien

+0

@Sjakelien你对此有了一个结论吗? –

+0

好的,是的。我决定,尽管比较慢,但反馈比没有反馈好。某种程度上,你的方法是有效的,所以我将这个答案作为答案投票,但实际上并没有提供顺畅的体验,因为动画的速度并不代表它应该指示的实际速度,如果这是有意义的:可以很容易地看到,它被逐步切碎。总而言之,由于进度条代表后台任务,因此用户界面仍然功能齐全,用户无需等待任何内容。 – Sjakelien