Re: NSDocument Serialization (-performSynchronousFileAccessUsingBlock: and friends)
Re: NSDocument Serialization (-performSynchronousFileAccessUsingBlock: and friends)
- Subject: Re: NSDocument Serialization (-performSynchronousFileAccessUsingBlock: and friends)
- From: Kyle Sluder <email@hidden>
- Date: Thu, 29 Sep 2011 12:00:02 -0700
On Thu, Sep 29, 2011 at 9:20 AM, Kevin Perry <email@hidden> wrote:
> If it were to call the fileAccessCompletionHandler any earlier then it might
> be possible, for example, for -fileModificationDate to be invoked on the
> main thread after -writeSafelyToURL: has written the file, but before the
> value has been properly updated.
Thank you, this is enlightening. Your sketch omitted the "take a
snapshot of the document wrapper" part; I assume that comes prior to
the call to -performAsynchronousFileAccess…, but still within the same
enveloping call to -performActivityWithSynchronousWaiting:….
However, I am still concerned about blocking other apps. According to
the documentation, -performAsynchronousFileAccessUsingBlock: does not
block the main thread. But it surely has to block _something_ until
the fileAccessCompletionHandler is called. We've guaranteed that we've
escaped the -performAsynchronousFileAccess stack frame by calling
dispatch_async(). Is it just blocking other NSFileCoordinator requests
until the fileAccessCompletionHandler is called? In that case, why is
the fileAccessCompletionHandler important for synchronizing with our
own main thread access, and how can it possibly protect our calls to
-fileURL from within the block passed to dispatch_async? Does
"-performAsynchronousFileAccess does not block the main thread" really
mean "if I can't execute the block now, I will execute it later, and
in doing so the thread on which this method was called (which might be
the main thread) will be blocked until the block has finished
executing _and_ the fileAccessCompletionHandler has been called"?
In my original example, I was using -performSynchronousFileAccess
around my call to -moveItemAtURL:toURL:error: and the subsequent call
to -presentError:, rather than -performAsynchronousFileAccess. If
-presentError: throws up an app-modal alert, then I've blocked any
other pending NSFileCoordinator clients who want to access my file,
correct? This can include other file presenters in my own app, who
might perhaps want to read the document in the background?
Or do I need to switch to -performAsynchronousFileAccess to make sure
I don't cause other apps to beachball? If so, would it look roughly
like this?
/**
* Again, not meant to be a good example of using NSFileManager.
**/
- (BOOL)isInHomeDirectory {
NSURL *fileURL = [self fileURL];
return [[fileURL absoluteString] hasPrefix:NSHomeDirectory()];
}
- (IBAction)doThing:(id)sender {
[self performActivityWithSynchronousWaiting:YES usingBlock:^{
[self performAsynchronousFileAccessUsingBlock:^(void
(^fileAccessCompletionHandler)(void){
dispatch_async(backgroundQueue, ^{
BOOL isInHome = [self isInHomeDirectory];
if (isInHome) {
NSURL *fileURL = [self fileURL];
NSURL destinationURL = [NSURL
fileURLWithPath:[NSTemporaryDirectory()
stringByAppendingPathComponent:[fileURL lastPathComponent]]];
NSError *error;
BOOL success = [[NSFileManager defaultManager]
moveItemAtURL:fileURL toURL:destinationURL error:&error];
[self continueAsynchronousWorkOnMainThreadUsingBlock:^{
fileAccessCompletionHandler();
if (!success)
[self presentError:error];
}];
}
});
}];
}];
}
All -performActivityWithSynchronousWaiting:usingBlock: is doing here
is wrapping a call to -performAsynchronousFileAccessUsingBlock:, which
in turn is just wrapping a call to dispatch_async. Do I need to
reimplement my own analogue to -unblockUserInteraction, to ensure the
user doesn't make any changes to the document while the move operation
is taking place on my backgroundQueue? Or is that scenario specific to
the conflict between "save the document asynchronously" vs "manipulate
the document's data?"
Sorry to bombard you with questions, but the headerdoc only goes so far.
--Kyle Sluder
_______________________________________________
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