为啥在应用程序已经运行时不调用 application:openFile: ?

Posted

技术标签:

【中文标题】为啥在应用程序已经运行时不调用 application:openFile: ?【英文标题】:Why isn't application:openFile: called when the application is already running?为什么在应用程序已经运行时不调用 application:openFile: ? 【发布时间】:2018-06-22 22:32:29 【问题描述】:

当用户双击由我的应用程序创建的文件或将此类文件拖到停靠图标上时,我想处理打开事件。

因此,我实现了NSApplicationDelegateapplication:openFile:application:openFiles: 方法,它们在应用程序未运行时按预期工作。

但是,如果在打开事件发生时应用程序已经在运行,则应用程序将获得焦点,但上述方法永远不会被调用(其中的断点不会被命中)并且文件不会打开。

我也尝试实现application:openURLs:。此方法具有相同的行为:如果事件发生时应用程序已经在运行,则不会调用它。

当应用程序已经在运行时,我是否需要实现不同的函数来处理打开的文件,或者为了在这些情况下调用现有函数,我还需要执行/设置其他操作吗?

【问题讨论】:

应用是基于文档的吗? @Willeke 不是。 如何在新项目中重现该问题? 我试过了,效果很好。 @Willeke 所以我使用了正确的 API,但我的项目中有一些其他设置/代码阻止它在应用程序已经运行时工作。感谢您的信息。 【参考方案1】:

这在the documentation 中没有提到,但according to this answer application:openFile: 的工作方式是NSApplicationodoc Apple 事件转发给它的代表。

有了这些知识,我能够在应用程序中找到以下旧的 Carbon 调用:

osError = AEInstallEventHandler(kCoreEventClass,
                                kAEOpenDocuments,
                                g_OpenDocumentsUPP,
                                0L,
                                false);

我假设这个现有的事件处理程序在 NSApplication 有机会处理它之前消耗了 Apple 事件。但是,当应用程序尚未运行时,NSApplication 在调用上述设置事件处理程序的行之前处理事件,因此行为不同。

从构建中删除这个旧代码导致NSApplicationDelegate 方法被调用,从而解决了这个问题。

【讨论】:

【参考方案2】:

下面的方法有效吗?

- (void)application:(NSApplication *)application 
       openURLs:(NSArray<NSURL *> *)urls;

If your delegate implements this method, AppKit does not call the
application:openFile: or application:openFiles: methods.

【讨论】:

application:openURLs: 具有相同的行为:当应用程序运行时它可以正常工作,但当应用程序运行时它不会被调用正在运行。

以上是关于为啥在应用程序已经运行时不调用 application:openFile: ?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在组件加载时不调用 useEffect(()=...,[]) ?

为啥在页面转换时不调用 next-auth jwt 回调?

为啥这个 constexpr 静态成员函数在调用时不被视为 constexpr?

为啥 useEffect 钩子在第一次渲染时不调用函数?

为啥 sys.exit() 在 Python 的线程内调用时不退出?

为啥观察 LiveData 时不调用 onChanged()