2014-02-15 129 views
-1

我希望能够在函数每循环一次循环时执行延迟。我已经有一个环的设置,如下所示:Objective-C时间延迟

for (float batteryPercentage = 1; batteryPercentage <= 0; batteryPercentage -= 0.01) 
    { 
     double timeUntilNextDegreeDrop = 9.0; 
     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeUntilNextDegreeDrop * NSEC_PER_SEC)); 
     dispatch_after (time, dispatch_get_main_queue(), ^(void) 
     { 
      [batteryLevel setProgress:batteryPercentage animated:YES]; 

      float batteryLevelPercentage = batteryPercentage * 100; 
      batteryLevelLabel.text = [NSString stringWithFormat:@"Battery Level: %f%%", batteryLevelPercentage]; 
     }); 
    } 

batteryPercentage是我试图通过0.01每9秒内从1递减到0直到该值到达0的节目的总长度可变应900秒(15分钟)。每9秒钟,我希望此代码每9秒执行一次,并更改名为batteryLevelUIProgressView的值。然后,我想将batteryPercentage乘以100,得到整个百分比数字,例如乘以0.67得到67,然后用新值替换batteryLevelLabel文本。当我尝试执行此操作时,batteryLevel Progress View不会填充,文本也不会更改。我假设计时器有问题,那么输入9秒延迟的更有效方法是什么?

+1

你为什么不使用'NSTimer'? – Wain

+0

@Wain如果我要实现一个'NSTimer',我会怎么做呢? – James

+1

http://stackoverflow.com/questions/1449035/how-do-i-use-nstimer/1449104#1449104 – Wain

回答

0

尝试的NSTimer的建议

[NSTimer scheduledTimerWithTimeInterval:9.0 
target:self 
selector:@selector(targetMethod:) 
userInfo:nil 
repeats:YES]; 

// targetMethod都会被调用9秒 //调用 [myTimer invalidate]; myTimer = nil;当你的任务完成

+0

如果所有的后台线程在一个循环的同时开始封杀后台线程也无济于事。并阻塞主线程是不是一个很好的计划...... – Wain

-1

您可以使用+ (void)sleepUntilDate:(NSDate *)aDate

+0

我不知道这一个,但我想你也可以使用'睡眠(9000);'来暂停你的线程9秒! –

+0

这段代码需要在主线程上运行。永远不要睡主线。 –

0

这里有一个办法做到这一点,保持接近您现有的结构使用NSThread:

@interface MyThread : NSThread 
@end 

@implementation MyThread 

-(void)main 
{ 
    NSDate * when = [ NSDate date ] ; 

    for (int battery = 1000; battery >= 0; battery -= 1) 
    { 
     when = [ NSDate dateWithTimeInterval:1.0 sinceDate:when ] ; 
     [ NSThread sleepUntilDate:when ] ; 

     [ [ NSThread mainThread ] perform:^{ 
      [batteryLevel setProgress:(CGFloat)battery/10.0 animated:YES]; 
      batteryLevelLabel.text = [NSString stringWithFormat:@"Battery Level: %f%%", (CGFloat)battery/10.0 ]; 
     }]; 
    } 
} 

@end 

帮手类别

@implementation NSThread (Perform) 

-(void)_perform:(void(^)())block 
{ 
    block() ; 
} 

-(void)perform:(void(^)())block 
{ 
    BOOL wait = [ NSThread currentThread ] == self ; 
    [ self performSelector:@selector(_perform:) onThread:self withObject:[ block copy ] waitUntilDone:wait ] ; 
} 

@end 

然后启动定时器NSThread * thread = [ [ MyThread alloc ] init ] ; [ thread start ] ;

可能更容易只是返工您的应用程序使用标准的NSTimer +回调结构...

(我也使用GCD看到做了一是什么样子:

dispatch_queue_t q = dispatch_queue_create(NULL, NULL) ; 
dispatch_async(q, ^{ 
    NSDate * when = [ NSDate date ] ; 

    for (int battery = 1000; battery >= 0; battery -= 1) 
    { 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      [batteryLevel setProgress:(CGFloat)battery/10.0 animated:YES]; 
      batteryLevelLabel.text = [NSString stringWithFormat:@"Battery Level: %f%%", (CGFloat)battery/10.0 ]; 
     }) ; 

     when = [ NSDate dateWithTimeInterval:1.0 sinceDate:when ] ; 
     [ NSThread sleepUntilDate:when ] ; 
    } 
}) ; 

(但我不认为这是保证不同队列在不同的线程)