AppleScript/OSAKit/Cocoa 应用程序间通信内存泄漏
AppleScript/OSAKit/Cocoa Inter-Application Communication Memory Leak
我有一个支持各种 AppleScript 命令的应用程序,当我将 list
(数组)对象从脚本传递到应用程序时,我 运行 遇到了内存泄漏问题。关于将 AppleScript 支持添加到您的 cocoa 应用程序,没有大量 100% 清晰且有用的文档,所以我希望这只是我的一个简单的 oversight/error,有人可以帮助我找到它。
我的最终目标是通过 OSAKit
编译另一个 Cocoa 应用程序并 运行 脚本,但我也使用 macOS 的 Script [=46] 进行了测试=] 传递一个 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
class,可以接收和响应 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="record"
而不是 type="list of text"
。这意味着我必须将一些 useless/duplicate 信息(密钥名称)传递到我的主应用程序中,但这是可以接受的,因为它现在没有泄漏并且据我所知不会花费任何额外的 CPU。
<command name="update database" code="MyApUpDB" description="Update the database">
<parameter name="with things" code="optn" type="record" optional="yes" description="">
<cocoa key="things"/>
</parameter>
<cocoa class="MyScriptHandler"/>
</command>
然后,我更新了 AppleScript 以传递 record
而不是 list
:
-- This AppleScript command does NOT cause leaks
tell application "MyApp"
update database with things {thing1:"thing1", thing2:"thing2", thing3:"thing3"}
end tell
我有一个支持各种 AppleScript 命令的应用程序,当我将 list
(数组)对象从脚本传递到应用程序时,我 运行 遇到了内存泄漏问题。关于将 AppleScript 支持添加到您的 cocoa 应用程序,没有大量 100% 清晰且有用的文档,所以我希望这只是我的一个简单的 oversight/error,有人可以帮助我找到它。
我的最终目标是通过 OSAKit
编译另一个 Cocoa 应用程序并 运行 脚本,但我也使用 macOS 的 Script [=46] 进行了测试=] 传递一个 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
class,可以接收和响应 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="record"
而不是 type="list of text"
。这意味着我必须将一些 useless/duplicate 信息(密钥名称)传递到我的主应用程序中,但这是可以接受的,因为它现在没有泄漏并且据我所知不会花费任何额外的 CPU。
<command name="update database" code="MyApUpDB" description="Update the database">
<parameter name="with things" code="optn" type="record" optional="yes" description="">
<cocoa key="things"/>
</parameter>
<cocoa class="MyScriptHandler"/>
</command>
然后,我更新了 AppleScript 以传递 record
而不是 list
:
-- This AppleScript command does NOT cause leaks
tell application "MyApp"
update database with things {thing1:"thing1", thing2:"thing2", thing3:"thing3"}
end tell