Obj-C,NSTimer循环调度,正确模式



我有一个完成处理程序(在web视图中评估javascript),在里面我调用了一个NSTimer,我已经将其封装成一个函数…

-(void)runJSAndGoto: (WKWebView*)web
js: (NSString*)js
selector: (SEL)aSelector
position: (NSString*)position
wait_period: (double)wait_period
user_info: (id)user_info
{
[web evaluateJavaScript:js completionHandler:^(id result, NSError * error) {
[NSTimer scheduledTimerWithTimeInterval: wait_period
target: self
selector: aSelector
userInfo: user_info
repeats: NO;
if(error)
{
NSLog(@"nn%@ error n%@n", position, error.description);
}
}];
}

所以我可以调用不同的javascript,并在完成后执行另一个函数,也许可以调用更多的javascript等。

好吧,这是我的问题。。。

稍后,我在一个循环中调用这个函数,该函数在完成时依次运行其他几个javascript调用。

  • 循环启动
    • 第一个js调用
      • 第一个js完成,等待2秒
        • 第二个js调用

你可以看到我要用这个去哪里。基本上,循环中的第一个调用运行了很多(直到第一个等待期)等等。这有点混乱。

  • 循环启动
    • 第一次呼叫
    • 第一次呼叫
    • 第一次呼叫等,直到2秒过去
      • 第二次呼叫

我希望在下一次循环迭代开始之前完成完整的"堆栈"。我正在写一个mac应用程序。

您可能正在寻找的标准模式是这样的:

- (void) doLoop: (NSInteger) i {
NSLog(@"%li", i);
if (i == 0) return;
NSTimeInterval delay = 2;
dispatch_time_t popTime = dispatch_time(
DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[self doLoop: i-1];
});
}

如果您调用[self doLoop:5],这就是您在控制台中看到的内容(注意时间,间隔约两秒):

2017-10-17 12:05:19.379507-0700 DelayLooper[1405:48726] 5
2017-10-17 12:05:21.563981-0700 DelayLooper[1405:48726] 4
2017-10-17 12:05:23.679977-0700 DelayLooper[1405:48726] 3
2017-10-17 12:05:25.863872-0700 DelayLooper[1405:48726] 2
2017-10-17 12:05:28.047187-0700 DelayLooper[1405:48726] 1
2017-10-17 12:05:30.247125-0700 DelayLooper[1405:48726] 0

你应该能够很容易地将其适应你想要做的任何事情。例如,你可以通过一系列选择器并调用它们,而不是递减计数变量。

最新更新