【问题标题】:How to implement custom NSApplication terminate: behavior in Cocoa?如何实现自定义 NSApplication 终止:Cocoa 中的行为?
【发布时间】:2011-03-25 10:02:50
【问题描述】:

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

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

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

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

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

    return NSTerminateNow;
}

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

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

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


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

  1. [NSApp terminate:self];foo(又名 self)调用。
  2. NSApp 发送其委托:[aDelegate applicationShouldTerminate:self];self 是 NSApp,而不是 foo)。
  3. aDelegate 接收消息并执行applicationShouldTerminate:(如果已实现)。

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


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

【问题讨论】:

    标签: cocoa terminate nsapplication


    【解决方案1】:

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

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

    【讨论】:

    • 非常感谢查克。 :) 你让我想到了正确的方向。我最终在 AppDelegate 中创建了“gracefulTermination”变量。我可以通过使用 [NSApp delegate] 访问 AppDelegate,调用 [appDelegate setGracefulTermination:NO],然后调用 [NSApp terminate:self]。当 AppDelegate 收到 applicationShouldTerminate: 消息时,它就会知道现在如何表现。除非其他人提出更好的答案,否则我会在 24 小时内将您的答案标记为正确。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 2020-01-10
    相关资源
    最近更新 更多