Obj-C,NSTimer 循环调度,模式正确吗?
Obj-C, NSTimer Schedule in a loop, correct pattern?
我有一个完成处理程序(在 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(@"\n\n%@ 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
您应该能够轻松地将其适应于您正在尝试做的任何事情。例如,您可以通过选择器列表并调用它们,而不是递减计数变量。
我有一个完成处理程序(在 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(@"\n\n%@ 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
您应该能够轻松地将其适应于您正在尝试做的任何事情。例如,您可以通过选择器列表并调用它们,而不是递减计数变量。