On Dec 31, 2008, at 12:11, Markus Spoettl wrote:

On Dec 31, 2008, at 11:29 AM, Quincey Morris wrote:
It's rather surprising that NSDocument's save-as-copy-and-move strategy that works so well for single files backfires so heavily in my case.
...
-- You need periodic housekeeping to detect orphaned files (due to saves that failed for some reason) and delete them.
...

It didn't occur to me when I wrote this that it might need an exclusive lock on the package to do this (and possibly other steps) safely.

If you can come up with any acceptable safe strategy, then it's still an issue how to integrate it into NSDocument. writeSafelyToURL: seems like the obvious place, but its documentation says "must call super" if overridden, and calling super is probably going to mess up your strategy.

That's what I thought too. What's the point of implementing a different way to safely save things when at the end you have to use the built-in behavior. It really doesn't make any sense, I believe this must be a documentation inaccuracy which really meant to say "be sure to call super unless you're doing you completely home-grown saving stuff on your own". Pure speculation of course.

Reading the comments in NSDocument.h is instructive. If it was just a case of replacing the built-in file-handling strategy with your own, I'd say go ahead and override without calling super. But the comments refer to mysterious "other things" that need to be done, so even if failing to call super works now it might break things in the future.

Which brings me to something else. How does one do that, meaning how can I provide a save progress. I can't use a second thread to save the document because (I think) AppKit expects that - writeSafelyToURL: returns when it's done. Starting a thread and off- loading the work there so that I can update the UI while the operation is going on isn't going to work. An asynchronous mechanism where I can tell the document what is has been saved similar to NSApplications -applicationShouldTerminate: and - replyToApplicationShouldTerminate: would be what I'd need for that. Currently the only way of doing a save progress with user interaction is rolling my own save operation altogether, which has lots of implications (for example the behavior when saving in the process of app termination). Am I overlooking something obvious here?

To do the save synchronously in the main thread with a progress sheet, I've had reasonable success sprinkling 'isCancelled' checks throughout the save code, and implementing 'isCancelled' like this:

- (BOOL) isCancelled {
        NSEvent *event;
while (event = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: nil inMode: NSEventTrackingRunLoopMode dequeue: YES])
                [NSApp sendEvent: event];
        return isOperationCancelled;
}

(The progress sheet's cancel button's action routine is responsible for setting isOperationCancelled to YES.) It's not elegant but it seems to work fine so long as it's called often enough.

Doing it asynchronously is more of a puzzle.
_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Reply via email to