循环延迟

时间:2013-08-08 11:06:55

标签: ios objective-c

我正在进行一段时间的循环而我正试图推迟它。

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,但这可能与其他内容有关。

7 个答案:

答案 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];它会根据你提供的时间停止你的线程