我正在将一些执行 AppleScripts 的代码从 NSAppleScript 迁移到 NSUserAppleScriptTask,以便我可以对我的应用程序进行沙箱处理。我遇到的问题可以最好地证明如下:
AppleScript“test.scpt”很简单
on run
display dialog "Hello World" buttons {"OK"} default button "OK"
end run
如果我使用如下 NSAppleScript 连续执行 10 次,则脚本会执行 10 次,每次执行都等待上一次执行完成。
NSURL *script = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"scpt"]];
for (int i=0; i<10; i++) {
NSDictionary *error = nil;
NSAppleScript *task = [[NSAppleScript alloc] initWithContentsOfURL:script error:nil];
[task executeAndReturnError:&error];
if (error!=nil) {
NSLog(@"AppleScript error: %@", error);
}
[task release];
}
但是使用 NSUserAppleScriptTask 似乎任务是同时执行的。并发执行是一个“问题”,因为如果前一个脚本打开了一个对话框,下一个要执行的脚本就会出错。这可以证明如下:
NSURL *script = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"scpt"]];
for (int i=0; i<10; i++) {
NSError *error;
NSUserAppleScriptTask *task = [[NSUserAppleScriptTask alloc] initWithURL:script error:&error];
[task executeWithCompletionHandler:^(NSError *error) {
if (error){
NSLog(@"Script execution failed with error: %@", [error localizedDescription]);
}
}];
[task release];
}
这会为 10 次执行中的 9 次生成以下错误:
execution error: "Hello World" doesn’t understand the «event sysodlog» message. (-1708)
我认为正确的解决方案是使用 gcd 或 NSOperationQueue 对每个操作进行排队,但我没有设法构建一个队列,等待 NSUserAppleScriptTask 的完成块在它开始下一个任务之前执行。
任何人都可以提出一个解决方案,它会给我与 NSAppleScript 方法给我的行为相同的行为吗?