NSUserAppleScriptTask返回大值永远不会调用completionHandler

时间:2015-09-09 15:48:54

标签: objective-c cocoa applescript

我有一个Objective-C应用程序正在使用NSUserAppleScriptTask来调用一些Applescript。 applescript返回的字符串大小不一。

它很好用,字符串很短。但是,当它变得很长时,它会开始无声地失败。如果它尝试返回长度为40,000个字符的字符串,则永远不会调用completionHandler,并且永远不会打印字符串returned ...。没有消息到日志,没有消息到控制台。它永远不会被召唤。

30,000个字符的字符串工作正常。我不确定精确截止点在哪里。

有没有人见过这个?是否有属性或配置设置我可以更改以增加此限制?或者我只需要放弃NSUserAppleScriptTask?

代码

NSURL* scriptURL = [[NSBundle mainBundle] URLForResource:@"ApplescriptHelper" withExtension:@"scpt"];
NSError* error;
NSUserAppleScriptTask* task = [[NSUserAppleScriptTask alloc] initWithURL:scriptURL error:&error];
NSLog(@"created task %@, error %@", task, error);

/* CREATE APPLE EVENT */
// taken from https://www.objc.io/issues/14-mac/sandbox-scripting/
ProcessSerialNumber psn = {0, kCurrentProcess};
NSAppleEventDescriptor *target = [NSAppleEventDescriptor descriptorWithDescriptorType:typeProcessSerialNumber bytes:&psn length:sizeof(ProcessSerialNumber)];

NSAppleEventDescriptor *function = [NSAppleEventDescriptor descriptorWithString:@"test"];

NSAppleEventDescriptor *event = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite eventID:kASSubroutineEvent targetDescriptor:target returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
[event setParamDescriptor:function forKeyword:keyASSubroutineName];
/* END CREATE APPLE EVENT */

[task executeWithAppleEvent:event completionHandler:^(NSAppleEventDescriptor*resultEventDescriptor, NSError *error) {
    NSLog(@"returned %@, error %@", resultEventDescriptor, error);

    if (!resultEventDescriptor) {
        NSLog(@"%s AppleScript task error = %@", __PRETTY_FUNCTION__, error);
    } else {
        NSLog(@"success")
    }
}];

ApplescriptHelper.scpt

on test()
    set str to ""
    repeat 40000 times
        set str to str & "x"
    end repeat
    return str
end fetchMusic

1 个答案:

答案 0 :(得分:2)

这看起来像是一个Apple bug。你应该提交一份报告。

使用以下调用图运行代码+ 2812 start (in libdyld.dylib) + 8 [0x7fff97a205b4] + 2812 exit (in libsystem_c.dylib) + 55 [0x7fff9157f403] + 2812 __cxa_finalize_ranges (in libsystem_c.dylib) + 345 [0x7fff9157f0ff] + 2812 std::__1::ios_base::Init::~Init() (in libc++.1.dylib) + 16 [0x7fff8f1ebd98] + 2812 std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush() (in libc++.1.dylib) + 68 [0x7fff8f1e2f5a] + 2812 std::__1::__stdoutbuf<char>::sync() (in libc++.1.dylib) + 137 [0x7fff8f1ec30d] + 2812 fflush (in libsystem_c.dylib) + 40 [0x7fff9155c31c] + 2812 __sflush (in libsystem_c.dylib) + 87 [0x7fff9155c3c0] + 2812 _swrite (in libsystem_c.dylib) + 87 [0x7fff91563e96] + 2812 __write_nocancel (in libsystem_kernel.dylib) + 10 [0x7fff918e57ba] 停止:

osascript

我认为你正在遇到pipe buffer limit of 65536 bytes

如果您使用NSUserAppleScriptTask使用的未记录的UTF-16参数,您将获得具有16字节标题和&amp;的原始AppleEvent输出。 32760编码文字。

repeat循环中超过32760的任何内容都会导致此行为。 2 * 16 + 65536 = <?php $first_name = $_POST['first-name']; $last_name = $_POST['last-name']; $email = $_POST['email']; $message = nl2br($_POST['message']); require 'PHPMailerAutoload.php'; $mail = new PHPMailer; //$mail->SMTPDebug = 3; // Enable verbose debug output $mail->isSMTP(); // Set mailer to use SMTP $mail->Host = ''; // Specify main and backup SMTP servers $mail->SMTPAuth = true; // Enable SMTP authentication $mail->Username = ''; // SMTP username $mail->Password = ''; // SMTP password $mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted $mail->Port = 587; $mail->addReplyTo( $email, $first_name ); $mail->addAddress( $email, $first_name ); $mail->addAddress( 'blah@fake.org', 'Staff' ); $mail->From = 'blah@fake.org'; $mail->FromName = 'Staff'; $mail->isHTML(true); // Set email format to HTML $mail->Subject = 'Hotel Room Request'; $mail->Body = $message; $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; if(!$mail->send()) { header('location: a_url_here'); } else { header('location: a_url_here'); }