如何实现自定义NSApplication终止:Cocoa中的行为?

时间:2010-08-04 18:08:45

标签: cocoa terminate nsapplication

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

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

如果在运行期间发生错误(例如数据库文件被删除),我会向用户显示错误,并为他们提供Recover选项(将文件放回并重试)或退出。如果选择退出,我想退出应用程序跳过数据库清理,因为它不再可能。从本质上讲,我喜欢这样的事情:

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

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

    return NSTerminateNow;
}

问题当然是获得 gracefulTermination 的价值。

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

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


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

  1. [NSApp terminate:self]; foo (a.k.a。 self )调用。
  2. NSApp发送其代理人:[aDelegate applicationShouldTerminate:self];自我是NSApp,而非 foo )。
  3. aDelegate接收消息并执行applicationShouldTerminate:
  4. foo 似乎在某处消失了,当 aDelegate 收到消息时,它已经消失了,只有NSApp显示为发件人。这可以防止我将foo内的infoDict或仅仅是一个简单的infoDict传递给包含自定义terminate:行为的aDelegate。


    我知道可以退出而不使用[NSApp terminate:...] exit()之类的applicationShouldTerminate:。虽然从我读过的内容来看,这是不受欢迎的,因为它对于Cocoa来说并不是犹太人。此外,它还可以防止在{{1}}内发生任何其他清理操作,这些操作即使在非正常退出时也不应跳过。

1 个答案:

答案 0 :(得分:3)

理想的解决方案是以这样的方式构建您的应用,即应用代理可以判断是否允许终止。

假设您的应用程序委托不可能以任何其他方式访问此信息(例如,哪个对象触发终止会影响它是否可能发生),这似乎是最简单的解决方案:子类NSApplication,给它一个{{1 }}属性并覆盖terminationInfo以设置此属性并调用super。