简体   繁体   English

情侣服务相关的“臭虫”

[英]Couple service related “bugs”

I've written an application that can be invoked as a service (by right-clicking a file in Finder and selecting to open it with my application), but there are a couple of unwanted side-effects when doing this. 我已经编写了一个可以作为服务调用的应用程序(通过在Finder中右键单击一个文件,然后选择用我的应用程序打开它),但是这样做有一些不良的副作用。

Example of service target method: 服务目标方法示例:

- (void)doSomething:(NSPasteboard *)pboard userData:(NSString *)userData error:(NSString **)error {
    NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
    NSLog(@"Selected file(s): %@", files);
    [self.anotherWindow makeKeyAndOrderFront:self];
}

1) When the application is launched this way (even if already open in debug mode), I seem unable to access other windows/controls from the doSomething function. 1)当以这种方式启动应用程序时(即使已经在调试模式下打开),我似乎无法从doSomething函数访问其他窗口/控件。 The above attempt to show "anotherWindow", for example, produces no errors, but doesn't "do" anything. 例如,以上尝试显示“ anotherWindow”的操作不会产生任何错误,但不会“执行”任何操作。 According to the stack trace, when inspected from -doSomething, all gui components have values 0x0000000000000000 - yet the application is displayed and fully functional. 根据堆栈跟踪,从-doSomething检查时,所有gui组件的值都为0x0000000000000000-但是该应用程序已显示且功能齐全。 It's only from -doSomething that I cannot reach them. 我只能通过-doSomething来联系他们。 "self" also has a different value when inspected from -doSomething versus -applicationDidFinishLaunching. 从-doSomething与-applicationDidFinishLaunching进行检查时,“ self”也具有不同的值。 I'm not sure how or why -doSomething is acquiring a different self/AppDelegate with uninitialized components. 我不确定-doSomething如何或为什么使用未初始化的组件获取不同的self / AppDelegate。 Seemingly fixed by [NSApp setServicesProvider:self]; 似乎由[NSApp setServicesProvider:self]修复;

2) I am not clear on how the system decides which copy of the application to launch when the service is invoked, but it usually doesn't pick the one I want. 2)我不清楚系统在调用服务时如何决定启动应用程序的哪个副本,但通常不会选择我想要的副本。 I have a copy in /Debug, a copy in /Release, a copy on my desktop... and if I delete one, it opens the file with another one instead (some sort of fallback-chain?). 我在/ Debug中有一个副本,在/ Release中有一个副本,在我的桌面上有一个副本...如果我删除了一个副本,它将用另一个副本打开文件(某种后备链?)。 How do I configure the service (in code or thru .plist) to open a specific version/location of this app? 如何配置服务(以代码或.plist形式)以打开此应用程序的特定版本/位置? But this is a dev machine. 但这是一台开发机。 If I release a distributable which installs to /Applications, do I ever really need to worry about this? 如果我发布了安装到/ Applications的可分发文件,我是否真的需要为此担心?

1) Double-check your XIB to makes sure that you've got everything hooked up correctly and then try launching the app with a breakpoint set at the NSLog above and verify that self.anotherWindow points at what you want. 1)仔细检查您的XIB,以确保您已正确连接所有内容,然后尝试在上面的NSLog设置断点的情况下启动应用程序,并验证self.anotherWindow是否指向您想要的内容。 If, for some reason, the breakpoint isn't firing, trying adding an: 如果由于某种原因断点没有触发,请尝试添加:

NSLog( @"Window: %@", self.anotherWindow);

To make sure everything is initialized and hooked up 确保所有内容都已初始化并已连接

2) The system uses Launch Services to determine which version of the application to launch. 2)系统使用Launch Services来确定要启动的应用程序版本。 Often it is the version most recently added to the system (which will cause the Launch Services database to be modified), but it is possible, depending on how your system is configured, that it won't be the version you expect. 通常,它是最新添加到系统的版本(这将导致Launch Services数据库被修改),但是根据系统的配置方式,它可能不是您期望的版本。

You can manually inquire and modify the launch services database using: 您可以使用以下方法手动查询和修改启动服务数据库:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister

(yeah, really long path). (是的,路很长)。 If you use the -dump option, that'll give you all of the data in the system (pipe into a file and search through it to get a better idea what's going on). 如果使用-dump选项,则将为您提供系统中的所有数据(将其存储到文件中并进行搜索以更好地了解正在发生的事情)。 If you search of the bundle id, you'll see all of the entries for the app. 如果搜索捆绑软件ID,您将看到该应用程序的所有条目。 Generally, most recent wins, but you can force a reload (instructions below). 通常,最近一次获胜,但是您可以强制重新加载(以下说明)。

If you just want to force a reload based on aa particular binary, use the -f flag and the path to the application: 如果只想基于特定的二进制文件强制重新加载,请使用-f标志和应用程序的路径:

..../lsregister -f /Applications/Foo.app

You can also use -u to explicitly unregister something. 您也可以使用-u显式注销某些内容。

Hopefully this will give you an idea what's going on here. 希望这可以使您了解这里发生的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM