Question

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
}

After 2 minutes of execution of this loop, the "time taken" increases from 200ms to 10s. Why? What is the problem ?

Was it helpful?

Solution

Assuming you are running in a multithreaded environment, answering your question would require a lot more information than you are giving us. Suffice to say, there is no guarantee that your sleeping thread will run "calling some method" exactly 200ms later, because that depends on what your other threads are doing.

Sleeping a thread like your example is generally considered a bad idea. Here's another way to accomplish what I think you are trying to do, but with ... better citizenship.

- (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
}

Finally, some observations:

  • -[NSDate timeIntervalSince1970] returns seconds (and fractions thereof, docs here), not milliseconds (although it has ms precision).

  • For timing, I find CFAbsoluteTime to be lighter weight:

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

OTHER TIPS

The general comments being made suggesting this is not the way to pause your loop are correct, you should look at other ways to do this - using blocks, GCD and routines such as dispatch_after is one approach.

However, to answer your actual question: sleeping is imprecise, you sleep for at least the time specified but maybe longer. E.g. from the sleep(3) manual page:

System activity may lengthen the sleep by an indeterminate amount.

Having said that, extend 0.2s to 10s does seem quite a long stretch. Look for other activity that might be kicking in and slowing you down, if you are on Mavericks consider its aggressive actions (app nap, timer coalescing, etc.).

But really, unless this is just test code look at partitioning it into A: test condition do part 1 and B: do part 2 then call A, or some other way, and use a timer callback or GCD to handle the pause.

HTH

Your code is wrong!!!

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
}

You're messing up your variables milliseconds and milliseconds1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top