【发布时间】:2021-05-07 07:17:04
【问题描述】:
我有一个支持各种 AppleScript 命令的应用程序,当将 list(数组)对象从脚本传递到应用程序时,我遇到了内存泄漏问题。关于将 AppleScript 支持添加到您的可可应用程序,没有大量 100% 清晰且有用的文档,所以我希望这只是我的一个简单的疏忽/错误,有人可以帮助我找到它。
我的最终目标是让另一个 Cocoa 应用程序通过 OSAKit 编译和运行脚本,但我也使用 macOS 的 Script Editor.app 进行了测试,以传递 list 和我的主要这样做时 Cocoa 应用程序仍然会泄漏:
-- This AppleScript command causes leaks
tell application "MyApp"
update database with things {"thing1", "thing2", "thing3"}
end tell
在我的另一个 Cocoa 应用程序(不是主要的 Cocoa 应用程序)中,我通过 OSAKit 运行上述程序,但它也在那里泄漏:
#import <OSAKit/OSAKit.h>
OSAScript *script= [[OSAScript alloc] initWithSource:[NSString stringWithFormat:@"tell application \"MyApp\"\nupdate database with things %@", listOfThings]];
NSDictionary * errorDict = nil;
NSAppleEventDescriptor *returnDescriptor = [script executeAndReturnError: &errorDict];
在接收端,我的主要 Cocoa 应用程序设置了一个 NSScriptCommand 类,并且可以接收和响应 AppleScript 命令,而不会出现任何其他已知问题。这是 list 部分的样子:
MyScriptHandler.h
#import "AppDelegate.h"
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
@interface MyScriptHandler : NSScriptCommand
- (NSAppleEventDescriptor *) performDefaultImplementation;
@end
**MyScriptHandler.m**
#import "MyScriptHandler.h"
@implementation MyScriptHandler
- (NSAppleEventDescriptor *) performDefaultImplementation
{
NSString* cmdName = [[self commandDescription] commandName];
if ([cmdName isEqualToString: @"update database"])
{
// GET THE LIST AND PASS IT OFF TO APP DELEGATE FOR PROCESSING
NSMutableArray *things = [[self evaluatedArguments] valueForKey:@"things"];
[(AppDelegate *)[[NSApplication sharedApplication] delegate] updateDatabaseFromAppleScript:options];
}
return [NSAppleEventDescriptor descriptorWithBoolean:YES];
}
不确定这是否有用,但我的主要 Cocoa 应用程序的 AppleScript 字典 (.sdef) 对于命令如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="MyApp Terminology">
<suite name="MyApp Suite" code="MyAp" description="Commands for MyApp">
<command name="update database" code="MyApUpDB" description="Update the database">
<parameter name="with things" code="optn" type="list of text" optional="yes" description="">
<cocoa key="things"/>
</parameter>
<cocoa class="MyScriptHandler"/>
</command>
</suite>
</dictionary>
【问题讨论】:
-
看看这个和你的答案,我认为问题出在你的 sdef 中,这里:
type="list of text"。这不是正确的 sdef 格式(我很惊讶它完全有效)。正确的格式应该是两个键值对:type="text" list="yes"我猜你发生内存泄漏是因为应用程序期望来自事件管理器的 text 描述符(它只是忽略了'list of ' 部分并看到 'text'),但正在接收 list 描述符。它以某种方式管理转换,但在此过程中造成泄漏。 -
@TedWrigley 非常感谢您的评论。这是非常有用的信息,我会试一试!
标签: objective-c cocoa memory-leaks applescript