Stopping the run loop for graceful exit


#1

Is there a graceful way to stop the run loop to cause a process to exit, without using the exit () function?

I have tried to use:

CFRunLoopStop ([[NSRunLoop currentRunLoop] getCFRunLoop]);

as suggested by Apple’s documentation but it doesn’t seem to have any affect.

Please see the code below - (void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)success:

[code]// ss.mm - Speak a given text string

#include
#include
#include <assert.h>
#import <Cocoa/Cocoa.h>

namespace my
{
void SpeakString (const std::string&);
}

int main (int nargs, char *argv[])
{
assert (nargs > 1);

const std::string text (argv [1]);
my::SpeakString (text);
return 0;
}

//
// Because we will be stuck in the run loop
// We use a delegate to cause the current process to exit after the Speech Synthesizer finishes speaking.
//
@interface SSDelegate: NSObject
@end

namespace my
{
void SpeakString (const std::string &string)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

  NSSpeechSynthesizer *ss = [[NSSpeechSynthesizer alloc] initWithVoice:[NSSpeechSynthesizer defaultVoice]];

  [ss setDelegate:[[SSDelegate alloc] init]];
  [ss startSpeakingString:[NSString stringWithFormat:@"%s", string.c_str ()]];

  // SS delegate will cause the process to exit
  // so that we don't get stuck here forever
  [runLoop run];

}
}

@implementation SSDelegate

  • (void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)success
    {
    std::cout << PRETTY_FUNCTION << std::endl;
    #if 1
    exit (0);
    #else
    CFRunLoopStop ([[NSRunLoop currentRunLoop] getCFRunLoop]);
    #endif
    }

@end
[/code]

To compile the above code: open the terminal application, create a scratch-pad directory, cd to that dir, create a directory named bin, copy and paste the code into a text file named ss.mm (in the scratch-pad dir) and run the command:

To run the resulting program, enter:

You should hear the numbers spoken.


#2

Hi!

You’ve got two choices. You can run your runloop with CFRunLoopRun() and stop it with CFRunLoopStop(). Or you can use one of the date-oriented calls (like -runUntilDate:) and poll to see if the speech synthesis is done. NSRunLoop’s -run is just a cover method that repeatedly runs one of the other calls, so the CFRunLoopStop() is just stopping one of those inner runloops but not the whole thing.

An old mailing list thread talks about this : cocoabuilder.com/archive/coc … pstop.html

Cheers,
++md