我正在尝试在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:
时,会发生这种情况:
[NSApp terminate:self];
由 foo (a.k.a。 self )调用。[aDelegate applicationShouldTerminate:self];
(自我是NSApp,而非 foo )。applicationShouldTerminate:
。 foo 似乎在某处消失了,当 aDelegate 收到消息时,它已经消失了,只有NSApp
显示为发件人。这可以防止我将foo内的infoDict或仅仅是一个简单的infoDict传递给包含自定义terminate:
行为的aDelegate。
我知道可以退出而不使用[NSApp terminate:...]
exit()
之类的applicationShouldTerminate:
。虽然从我读过的内容来看,这是不受欢迎的,因为它对于Cocoa来说并不是犹太人。此外,它还可以防止在{{1}}内发生任何其他清理操作,这些操作即使在非正常退出时也不应跳过。
答案 0 :(得分:3)
理想的解决方案是以这样的方式构建您的应用,即应用代理可以判断是否允许终止。
假设您的应用程序委托不可能以任何其他方式访问此信息(例如,哪个对象触发终止会影响它是否可能发生),这似乎是最简单的解决方案:子类NSApplication,给它一个{{1 }}属性并覆盖terminationInfo
以设置此属性并调用super。