我正在进行一段时间的循环而我正试图推迟它。
while (mode == 1)
{
[self performSelector:@selector(on) withObject:nil afterDelay:slider.value];
NSLog(@"on");
[self performSelector:@selector(off) withObject:nil afterDelay:slider.value];
NSLog(@"off");
}
但即使我将滑块设置为10秒,它也会非常快速地开启和关闭。
我的应用程序也是黑屏,我只看到状态栏和我的nslog,但这可能与其他内容有关。
答案 0 :(得分:2)
这就是你告诉你的应用:
“从现在开始slider.value
秒开启”
“从现在起slider.value
秒内关闭一些东西”
你觉得有问题吗?
答案 1 :(得分:2)
performSelector:withObject:afterDelay:
不等待选择器完成。这意味着只要您告诉选择器A在一定时间后运行,它会立即继续并告诉选择器B在一定时间后运行。有很多选择可以解决这个问题:
如果您想坚持选择器,可以使用performSelector:onThread:withObject:waitUntilDone:
。 确保您不使用主线程,否则您将遇到UI冻结。
[NSThread waitForInterval]
是另一种选择,但与上一个选项一样,将冻结UI,除非您在另一个线程上调用整个while循环。令我感到惊讶的是,在没有人注意到这一重要因素的情况下,已经提到了这一点。
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
答案 2 :(得分:0)
double delayInSeconds = slider.value;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self off];
//or
[self on];
});
这会在给定时间后执行块中的任何内容! :)
答案 3 :(得分:0)
while循环不会等待延迟的操作完成,它只是安排它们。问题是你要在一个非常快速的循环中安排所有事件,然后在10秒之后一个接一个地运行事件。
答案 4 :(得分:0)
[self performSelector:@selector(on) withObject:nil afterDelay:slider.value];
在此声明中,afterDelay并不意味着它会暂停一段时间。
这意味着方法“on”将在几秒钟后执行。但是执行不会等到完成方法“on”的执行并转到下一个语句。
如果您只想做一些延迟,可以使用以下语句:
[NSThread sleepForTimeInterval:2.0];
这将等待2秒钟。但这可能不是一个好主意,因为它会冻结你的UI。
我希望这会对你有所帮助。
一切顺利.....
答案 5 :(得分:0)
如果您想立即打开它并将其关闭指定的延迟:
[self on];
NSLog(@"on");
[self performSelector:@selector(off) withObject:nil afterDelay:slider.value];
NSLog(@"off");
如果您想在指定的延迟后打开它,请在10秒后再将其关闭:
[self performSelector:@selector(on) withObject:nil afterDelay:slider.value];
NSLog(@"on");
[self performSelector:@selector(off) withObject:nil afterDelay:slider.value + 10];
NSLog(@"off");
答案 6 :(得分:-1)
尝试使用[NSThread sleepForTimeInterval:1.0f];它会根据你提供的时间停止你的线程