performSelector:withObject:afterDelay:
不等待选择器完成。这意味着一旦您告诉选择器 A 在特定时间后运行,它会立即继续并告诉选择器 B 在特定时间后运行。有很多选项可以解决此问题:
如果您想坚持使用选择器,可以使用performSelector:onThread:withObject:waitUntilDone:
. 确保你不使用主线程,否则你会遇到 UI 冻结。
[NSThread waitForInterval]
是另一个选项,但与前一个选项一样,除非您在不同的线程上调用整个 while 循环,否则它将冻结 UI。我很惊讶在没有人注意到这个重要因素的情况下被提及了这么多。
GCD 是另一种选择。它不会等待它完成,因此您不应该遇到主要的 UI 冻结。
dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW, slider.value * NSEC_PER_SEC);
dispatch_after(dispatchTime, dispatch_get_main_queue(), ^(void){
[self on];
dispatch_after(dispatchTime, dispatch_get_main_queue(), ^(void){
[self off];
})
});
另一种选择是保留您现在正在做的事情并让选择器 B 在 slider.value*2 之后运行。如果您以数学方式考虑这一点,那是有道理的:
A) 0-1-2-3-4-5-6-7-8-9-10
B) 0-1-2-3-4-5-6-7-8-9-10-1-2-3-4-5-6-7-8-9-10