在Objective-C中暂停执行WHILE循环的最佳方法

时间:2014-02-20 17:25:17

标签: objective-c nsthread

while(...condition...)
{
    //do something
    NSDate *date = [NSDate date];
    NSTimeInterval milliseconds = [date timeIntervalSince1970];
    [NSThread sleepForTimeInterval:0.2];
    date = [NSDate date];
    NSTimeInterval milliseconds1 = [date timeIntervalSince1970];
    NSLog(@"**** time taken : %f",milliseconds1-milliseconds);
    //calling some method
}

执行此循环2分钟后,“所用时间”从200ms增加到10s。为什么?问题是什么 ?

3 个答案:

答案 0 :(得分:1)

假设您在多线程环境中运行,回答您的问题需要很多比您提供的更多信息。可以这么说,不能保证你的睡眠线程会在200ms之后运行“调用某种方法”,因为这取决于你的其他线程在做什么。

像你的榜样一样沉睡一般被认为是个坏主意。这是实现我认为你想做的事情的另一种方式,但是......有更好的公民身份。

- (void)loopIfNeeded
{
    if (...condition...) {
        // do something

        // ... and then call -someMethod ~200ms later
        [self performSelector:@selector(someMethod) withObject:nil afterDelay:0.2];
    }
}

 - (void)someMethod
{
    // whatever some method does

    [self loopIfNeeded]; // continue loop
}

最后,一些观察结果:

  • -[NSDate timeIntervalSince1970]返回秒(及其分数,文档here),而不是毫秒(尽管它具有ms精度)。

  • 对于时间安排,我发现CFAbsoluteTime重量更轻:

    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
    // do your thing
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    CFTimeInterval elapsed = start - end; // or just NSLog(@"elapsed %f", start - end);
    

答案 1 :(得分:0)

正在做出的一般性评论表明这不是暂停循环的方法是正确的,你应该看看其他方法来做到这一点 - 使用块,GCD和例如dispatch_after等例程是一种方法。

然而,要回答你的实际问题:睡觉是不精确的,你至少睡了一段时间,但可能更长。例如。来自sleep(3)手册页:

  

系统活动可能会使睡眠时间延长不确定。

话虽如此,将0.2秒扩展到10秒看起来确实相当长。寻找其他可能会踢你的活动并减慢你的速度,如果你在小牛队中考虑其积极行动(app nap,计时器合并等)。

但实际上,除非这只是测试代码,否则请将其分区为A:测试条件执行第1部分和B:执行第2部分然后调用A或其他方式,并使用计时器回调或GCD来处理暂停

HTH

答案 2 :(得分:-1)

你的代码错了!!!

while(...condition...)
{
    //do something
    NSDate *date = [NSDate date];
    NSTimeInterval milliseconds = [date timeIntervalSince1970];
    [NSThread sleepForTimeInterval:0.2];
    date = [NSDate date];
    NSTimeInterval milliseconds = [date timeIntervalSince1970]; // here should be milliseconds1
    NSLog(@"**** time taken : %f",milliseconds1-milliseconds);
    //calling some method
}

你搞乱了变量millisecondsmilliseconds1