Finally, I put the "saveDocument" in the "NIBDidLoad" method, with an 
"afterDelay:0". I was reluctant to use this "afterDelay:0" (I wish there were a 
method called "performOnNextRunLoop"). This smells like a hack !!!
It was easier to call the "saveDocument" than to subclass NSDocumentController, 
and result is safer I think. I don't have to deal with the case where no nib is 
loaded.

It works well.

Thanks to all for their help.

Colas



Le Mercredi 19 mars 2014 23h14, Colas B <colasj...@yahoo.fr> a écrit :
 
Thanks for this very complete answer.

If it can help, I can tell that I also tried to put the 'saveDocument:' in the 
'didLoadNIb' (without the 'afterDelay') and it also create deadlock. 



________________________________
 From:  Quincey Morris <quinceymor...@rivergatesoftware.com>; 
To:  Colas B <colasj...@yahoo.fr>; 
Cc:  cocoa-dev@lists.apple.com <cocoa-dev@lists.apple.com>; 
Subject:  Re: Saving while opening with NSDocument 
Sent:  Wed, Mar 19, 2014 10:09:54 PM 


On Mar 19, 2014, at 14:10 , Colas B <colasj...@yahoo.fr> wrote:


> I will try with 'withDelay:0' and will let you know if it works. If you have 
> a link for information on runloops (what is it, how it works, etc.), I am 
> interested.

You can get information on run loops here:

    
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html

and in the NSRunLoop class reference:

    
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html

However, just as it’s not about the time delay, it’s also not exactly about the 
run loop. Conceptually, the “top level” of app processing is a loop in the main 
thread:

    1. Get the next event or source.
    2. Process it.
    3. Repeat forever from step 1.

When you open a document, the ‘openDocument:’ action method is going to be 
invoked somewhere in an instance of step 2. Generally, it’s not “safe” to 
invoke another action method, such as ‘saveDocument:’ until the current
 one is finished executing. (And certainly not safe in your case, as you 
discovered.) So, when you detect that your data fix is needed, you simply need 
to defer initiation of the ‘saveDocument:’ action method until the next 
iteration of the above loop, which is generally called just “the run loop” 
because it’s implemented using a NSRunLoop. (It’s possible to run a NSRunLoop 
in other places, including other threads.)

Because it’s known that ‘performSelector:…afterDelay:’ detects expiration of 
the delay (even a delay of 0) in step 1 of the above loop, this is a convenient 
way (even with a delay of 0) to get something to happen in a future instance of 
step 2 of the loop. Thus, a lot of ancilliary machinery (selectors, timers, run 
loops, app architecture) is brought to bear on a conceptually simple but 
otherwise actually awkward problem: “do this other thing later”.

Note that it’s not impossible that ‘openDocument:’ — or some method it invokes 
internally — may possibly issue a ‘performSelector:…afterDelay:’ itself. (I 
don’t think it does, but it’s always a possibility.) The ‘performSelector’ 
methods are queued, so they will be invoked in the order issued. That’s one 
reason why I was suggesting you put yours as late as possible in the process 
(windowControllerDidLoadNib), but as Kyle pointed out if you want to be 
absolutely sure that the fix is saved to disk no matter how your NSDocument 
subclass came to be created, you may have to do that in a different place.
_______________________________________________

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