我编写了一个可以作为服务调用的应用程序(通过右键单击Finder中的文件并选择使用我的应用程序打开它),但这样做会产生一些不必要的副作用。 / p>
服务目标方法示例:
- (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)当以这种方式启动应用程序时(即使已经在调试模式下打开),我似乎无法从doSomething函数访问其他窗口/控件。例如,上面显示“anotherWindow”的尝试不产生任何错误,但不会“做”任何事情。根据堆栈跟踪,当从-doSomething进行检查时,所有gui组件的值都为0x0000000000000000 - 但应用程序显示并且功能完全正常。它只是来自-doSomething,我无法达到它们。从-doSomething与-applicationDidFinishLaunching进行检查时,“self”也有不同的值。我不确定如何或为什么-doSomething正在使用未初始化的组件获取不同的self / AppDelegate。看似由[NSApp setServicesProvider:self]修复;
2)我不清楚系统如何决定在调用服务时启动哪个应用程序副本,但它通常不会选择我想要的那个。我在/ Debug中有一个副本,在/ Release中有一个副本,在我的桌面上有一个副本......如果我删除一个,它会打开另一个文件(某种回退链?)。如何配置服务(在代码中或通过.plist中)以打开此应用程序的特定版本/位置?但这是一台开发机器。如果我发布一个可安装到/ Applications的distributable,我真的需要担心吗?
答案 0 :(得分:0)
1)仔细检查您的XIB,确保您已正确连接所有内容,然后尝试使用设置在NSLog
上方的断点启动应用,并验证self.anotherWindow
点是否为你想要什么。如果由于某种原因,断点未触发,请尝试添加:
NSLog( @"Window: %@", self.anotherWindow);
确保所有内容都已初始化并连接
2)系统使用Launch Services
来确定要启动的应用程序版本。通常它是最近添加到系统中的版本(这将导致Launch Services
数据库被修改),但是根据系统的配置方式,它可能不是您期望的版本
您可以使用以下方式手动查询和修改启动服务数据库:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister
(是的,真的很长的路)。如果您使用-dump
选项,那么它将为您提供系统中的所有数据(管道传输到文件中并搜索它以更好地了解正在发生的事情)。如果您搜索捆绑包ID,您将看到该应用的所有条目。通常,最近的胜利,但你可以强制重新加载(下面的说明)。
如果您只想基于特定二进制文件强制重新加载,请使用-f
标志和应用程序的路径:
..../lsregister -f /Applications/Foo.app
您还可以使用-u
明确取消注册。
希望这会让你知道这里发生了什么。