How do I force *all* NSDocument dialogs to be handled SYNCHRONOUSLY?

NSDocument continues to be a software maintenance nightmare.

Asynchronous NSDocument dialogs should be the exception, not the rule, 
*especially* in these cases:

  NSApp knows its being asked to terminate.
  NSApp knows it hasn't finished loading.


http://stackoverflow.com/questions/16360898/nsdocument-savedocumentwithdelegate-deadlocked-during-app-termination



BEGIN EDIT: I *may* have found a solution that allows me to wait synchronously
------------------------------------------------------------------------
Can anyone verify that this would be an "Apple approved" solution?

    static BOOL sWaitingForDidSaveModally = NO;
    BOOL gWaitingForDidSaveCallback = NO; // NSDocument dialog calls didSave: 
when done

 

    ...
      gWaitingForDidSaveCallback = true;
      [toDocument saveDocumentWithDelegate:self 
                           
didSaveSelector:@selector(document:didSave:contextInfo:)  
                               contextInfo:nil];
       if ( gWaitingForDidSaveCallback )
       {
          // first, dispatch any other potential alerts synchronously
          while ( gWaitingForDidSaveCallback && [NSApp modalWindow] )
             [NSApp runModalForWindow: [NSApp modalWindow]];
          
          if ( gWaitingForDidSaveCallback )
          {
             sWaitingForDidSaveModally = YES;
             [NSApp runModalForWindow: [NSApp mbWindow]]; // mbWindow is our 
big (singleton) window
             sWaitingForDidSaveModally = NO;
          }
       }
    ...


    - (void)document:(NSDocument *)doc didSave:(BOOL)didSave contextInfo:(void  
*)contextInfo
    {
       [self recordLastSaveURL];
       gWaitingForDidSaveCallback = NO;
       if ( sWaitingForDidSaveModally )
          [NSApp stopModal];
      
    }
END EDIT
------------------------------------------------------------------------

I have to support Snow Leopard/Lion/ML

App termination is an ugly process.
When the user decides to quit, and the document has changes that need saving, I 
call this:

      gWaitingForDidSaveCallback = true;
      [toDocument saveDocumentWithDelegate:self 
                           
didSaveSelector:@selector(document:didSave:contextInfo:)  
                               contextInfo:nil];

I *really really really* want this call to be synchronous, but in latest Lion, 
this hangs my app: 

       while ( gWaitingForDidSaveCallback )
       {
          // didSave: callback clears sWaitingForDidSaveCallback
          // do my own synchronous wait for now
          [[NSRunLoop currentRunLoop] runUntilDate:[NSDate 
dateWithTimeIntervalSinceReferenceDate:0.05]];
       }


My best guess for the hang is that the mouseDown: of a window close button
is confusing the NSDocument.

So now, I have to return, and pepper my apps main loop with unmaintainable 
state machine logic to prevent user from executing various dangerous hotkeys.

Ok, so I grin and bear it, and run into yet another roadblock!

In previous OS versions/SDKs, [NSApp modalWindow] would return a window when it
was in this state.  Now it doesn't!  Grrrrr...  
NSDocument has no API to test when it is in this state!

So, now there is no mechanism to globally check this state!
I have to add yet another state variable to my state machine.


Anyone have a cleaner solution for this problem that works in all OS versions 
and all present (and future) SDKs?




_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to