Re: Re : Re: Saving while opening with NSDocument
Re: Re : Re: Saving while opening with NSDocument
- Subject: Re: Re : Re: Saving while opening with NSDocument
- From: Colas B <email@hidden>
- Date: Mon, 24 Mar 2014 17:05:36 +0000 (GMT)
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 <email@hidden> 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 <email@hidden>;
To: Colas B <email@hidden>;
Cc: email@hidden <email@hidden>;
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 <email@hidden> 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 (email@hidden)
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:
This email sent to email@hidden