3

我正在尝试在 Cocoa 应用程序中实现自定义终止行为。通常,当我的应用程序正常退出时,它会执行最终运行时数据库清理,然后退出。NSApplication每当[NSApp terminate:aSender]被调用时,这都会在 AppDelegate(的委托)内部发生:

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
    // database cleanup...
    return NSTerminateNow;
}

如果在运行时发生错误(例如数据库文件被删除),我会向用户显示错误,并让他们选择恢复(放回文件并重试)或退出。如果选择退出,我想退出应用程序跳过数据库清理,因为它不再可能。本质上,我想要这样的东西:

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
    BOOL gracefulTermination = ...;

    if (gracefulTermination == YES)
    {
        // Database cleanup....
    }

    return NSTerminateNow;
}

当然,问题在于获取gracefulTermination的值。

有没有办法将自定义变量传递给NSApp何时terminate:被调用,例如 infoDict,然后在内部接收它applicationShouldTerminate:

如果没有,是否有更好的方法来完成自定义终止行为?


据我所知,当terminate:被其他对象调用时,会发生这种情况:

  1. [NSApp terminate:self];foo(又名self)调用。
  2. NSApp 发送它的委托:([aDelegate applicationShouldTerminate:self];selfNSApp,不是foo)。
  3. aDelegate 接收消息并applicationShouldTerminate:在实现时执行。

foo似乎在某处消失了,当aDelegate收到消息时,它已经永远消失了,只NSApp显示为发件人。这可以防止我将 foo 中的 infoDict 或只是一个普通的 infoDict 传递给包含自定义terminate:行为的 Delegate。


我知道不使用[NSApp terminate:...]类似exit(). 虽然从我所读到的内容来看,这是不受欢迎的,因为它不适合可可。此外,它还可以防止在内部发生任何其他清理操作applicationShouldTerminate:,即使在非正常退出期间也不应跳过这些操作。

4

1 回答 1

3

理想的解决方案是以应用程序委托可以判断是否允许终止的方式构建您的应用程序。

假设您的应用程序委托无法以任何其他方式访问此信息(例如,哪个对象触发的终止会影响它是否会发生),这似乎是最简单的解决方案:子类 NSApplication,给它一个terminationInfo属性并覆盖terminate:以设置它财产并打电话给超级。

于 2010-08-04T18:15:57.017 回答