Re: how do I save prefs when the app is Force Quit?
Re: how do I save prefs when the app is Force Quit?
- Subject: Re: how do I save prefs when the app is Force Quit?
- From: Shaun Wexler <email@hidden>
- Date: Sun, 14 May 2006 20:13:00 -0700
On May 14, 2006, at 1:12 PM, Agent M wrote:
I would argue that the default behavior for "Force Quitting" in
Cocoa applications is also the most appropriate. If the user is
force quitting the app (SIGTERM->SIGKILL), then something has gone
awry in the app; saving the settings which caused the unexpected
error may bring the same error back the next time the app is opened.
Quit and Force Quit should absolutely behave differently.
I completely agree. That said (ie you have been warned, std
disclaimer, written in Mail, YMMV, etc), here is how to do it, FTA:
#import <signal.h>
#import <mach/mach_error.h>
mach_port_t signalMachPort;
mach_msg_header_t signalMachPortHeader;
static mach_port_t SignalHandlerGetPort(void *info)
{
return signalMachPort;
}
static void *SignalHandlerPerform(void *msg, CFIndex size,
CFAllocatorRef allocator, void *info)
{
if (msg) {
int sig = ((mach_msg_header_t *)msg)->msgh_id;
if (sig == SIGQUIT || sig == SIGTERM) {
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
return NULL;
}
static void SignalHandlerSendMessage(int sig)
{
if (sig == SIGQUIT || sig == SIGTERM) {
signalMachPortHeader.msgh_id = sig;
mach_msg_send(&signalMachPortHeader);
}
// test mask here and optionally forward signal down the handler
chain /* man 3 signal */
}
void InstallSignalHandler(void)
{
assert(pthread_main_np());
if ((signalMachPort = mach_reply_port()))
{
bzero(&signalMachPortHeader, sizeof(signalMachPortHeader));
signalMachPortHeader.msgh_bits = MACH_MSGH_BITS
(MACH_MSG_TYPE_COPY_SEND, 0);
signalMachPortHeader.msgh_size = sizeof(signalMachPortHeader);
signalMachPortHeader.msgh_remote_port = signalMachPort;
signalMachPortHeader.msgh_local_port = MACH_PORT_NULL;
signalMachPortHeader.msgh_id = 0;
CFRunLoopSourceContext1 context = {
.version = 1,
.info = NULL,
.retain = NULL,
.release = NULL,
.copyDescription = NULL,
.equal = NULL,
.hash = NULL,
.getPort = SignalHandlerGetPort,
.perform = SignalHandlerPerform
};
CFRunLoopSourceRef source;
if ((source = CFRunLoopSourceCreate(NULL, 0,
(CFRunLoopSourceContext *)&context))) {
CFRunLoopAddSource(CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode);
signal(SIGQUIT, SignalHandlerSendMessage, YES);
signal(SIGTERM, SignalHandlerSendMessage, YES);
}
}
}
--
Shaun Wexler
MacFOH
http://www.macfoh.com
To the optimist, the glass is half full.
To the pessimist, the glass is half empty.
To the programmer, the glass is twice as big as it needs to be.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden