Objective c NSTimer间隔时间设置
Objective c NSTimer interval time setting
点击"startButton"按钮后,触发定时器每5秒执行一次"myCalculation"。
问题:myCalculation 方法的执行时间大约需要 5-10 秒才能完成
Q1.How 我可以给定时器设置一个合适的时间间隔吗? (我认为设置时间间隔为 10s 太长了,如果 retrieveAndUpdateNews 花费 5s 完成,程序将空闲 5s)
目前情况下,虽然myCalculation需要10s完成,但是定时器会跳到执行retrieveAndUpdateNews,5s后触发retrieveAndUpdateNews。
Q2.Are 这对我的应用程序来说是一个潜在的问题吗?
谢谢你的时间。
-(IBAction) startButton : (id)sender{
NSTimer * myTimer;
timer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(retrieveAndUpdateNews)
userInfo:nil repeats:YES];
}
-(void)retrieveAndUpdateNews{
//some calculation spend 5 - 10 sec.
}
猜测您的计算将花费多少时间可能不是正确的方法(特别是因为它会因不同的设备而异)。为什么不使用 gcd
并在计算完成时收到 "callback"?
它可能看起来像这样(假设您想在后台线程上执行计算):
- (IBAction)startButton:(id)sender {
[self doSomethingWithCompletionCallback:^{
[self retrieveAndUpdateNews];
}];
}
- (void)doSomethingWithCompletionCallback:(void (^)(void))callback {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/// do some work
callback();
});
}
听起来你真正想要的是当用户按下按钮时启动你的计时器,然后在服务器上处理和下载数据时停止它,然后在收到数据后重新启动它以便你可以刷新再次。类似于:
- (IBAction) startButton:(id)sender {
[self beginDownloadCycle];
}
- (void)beginDownloadCycle {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(retrieveAndUpdateNews)
userInfo:nil
repeats:NO];
}
- (void)retrieveAndUpdateNews {
// some calculation spend 5 - 10 sec with completion block.
[... :^() {
[self beginDownloadCycle];
}];
}
请注意,应保留计时器,以便您可以在需要时取消它,这样您就知道发生了什么(因此 self.myTimer =
)。
要避免此问题,您可以使用
- (void)performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay
同样在您的 "retrieveAndUpdateNews" 中使用 performSelector 再次调用该方法。所以它要进行递归调用。要取消 performSelector 使用
- (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget
点击"startButton"按钮后,触发定时器每5秒执行一次"myCalculation"。 问题:myCalculation 方法的执行时间大约需要 5-10 秒才能完成
Q1.How 我可以给定时器设置一个合适的时间间隔吗? (我认为设置时间间隔为 10s 太长了,如果 retrieveAndUpdateNews 花费 5s 完成,程序将空闲 5s)
目前情况下,虽然myCalculation需要10s完成,但是定时器会跳到执行retrieveAndUpdateNews,5s后触发retrieveAndUpdateNews。
Q2.Are 这对我的应用程序来说是一个潜在的问题吗? 谢谢你的时间。
-(IBAction) startButton : (id)sender{
NSTimer * myTimer;
timer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(retrieveAndUpdateNews)
userInfo:nil repeats:YES];
}
-(void)retrieveAndUpdateNews{
//some calculation spend 5 - 10 sec.
}
猜测您的计算将花费多少时间可能不是正确的方法(特别是因为它会因不同的设备而异)。为什么不使用 gcd
并在计算完成时收到 "callback"?
它可能看起来像这样(假设您想在后台线程上执行计算):
- (IBAction)startButton:(id)sender {
[self doSomethingWithCompletionCallback:^{
[self retrieveAndUpdateNews];
}];
}
- (void)doSomethingWithCompletionCallback:(void (^)(void))callback {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/// do some work
callback();
});
}
听起来你真正想要的是当用户按下按钮时启动你的计时器,然后在服务器上处理和下载数据时停止它,然后在收到数据后重新启动它以便你可以刷新再次。类似于:
- (IBAction) startButton:(id)sender {
[self beginDownloadCycle];
}
- (void)beginDownloadCycle {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:@selector(retrieveAndUpdateNews)
userInfo:nil
repeats:NO];
}
- (void)retrieveAndUpdateNews {
// some calculation spend 5 - 10 sec with completion block.
[... :^() {
[self beginDownloadCycle];
}];
}
请注意,应保留计时器,以便您可以在需要时取消它,这样您就知道发生了什么(因此 self.myTimer =
)。
要避免此问题,您可以使用
- (void)performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay
同样在您的 "retrieveAndUpdateNews" 中使用 performSelector 再次调用该方法。所以它要进行递归调用。要取消 performSelector 使用
- (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget