I'm working on a document-based application, and am a bit befuddled by -performSynchronousFileAccessUsingBlock:. The documentation says that "NSDocument itself consistently uses this mechanism around invocations of the following methods:" and lists methods including -fileType, -fileURL, etc. The documentation for -performAsynchronousFileAccessUsingBlock: says "saveToURL:ofType:forSaveOperation:completionHandler: uses this method instead of performSynchronousFileAccessUsingBlock:," but doesn't explain _how_ it uses it.
So what's the appropriate pattern if I need to make a decision based on the return value of one of these methods, and potentially manipulate the file to do so? Is the following safe? /** * Please forgive the terrible abuse of path- and URL-based APIs here. * This isn't a good example of how to deal with files. I'm more concerned * with exploring the serialization patterns. **/ - (BOOL)isInHomeDirectory { __block NSURL *fileURL; [self performSynchronousFileAccessUsingBlock:^{ fileURL = [self fileURL]; }]; return [[fileURL absoluteString] hasPrefix:NSHomeDirectory()]; } - (IBAction)doThing:(id)sender { BOOL isInHome = [self isInHomeDirectory]; [self performActivityWithSynchronousWaiting:YES usingBlock:^{ // Async operations might've moved us if (isInHome && [self isInHomeDirectory]) { __block NSURL *fileURL; [self performSynchronousFileAccessUsingBlock:^{ fileURL = [self fileURL]; }]; NSURL destinationURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[fileURL lastPathComponent]]]; NSError *error; BOOL success = [[NSFileManager defaultManager] moveItemAtURL:fileURL toURL:destinationURL error:&error]; if (!success) [self presentError:error]; } }]; } //-----END-----// I'm getting the impression that my use of -performSynchronousFileAccess… around the minimal calls to -fileURL is not safe. But you can't call -performActivityWithSynchronousWaiting:… within the block passed to -performSynchronousFileAccess…. So I don't know what to do. Should I move my call to -performActivity… as high up as possible? Do I need to wrap my call to -[NSFileManager moveItemAtURL:toURL:error:] in another call to -performSynchronousFileAccess…? Can I nest calls to -performSynchronousFileAccess…, or will that deadlock? The following seems like it could be more correct, but it nests calls to -performSynchronousFileAccess… and it seems to do a whole lot within that synchronous block. Will that block other apps that are waiting to perform coordinated reads and writes on that file? /** * Again, not meant to be a good example of using NSFileManager. **/ - (BOOL)isInHomeDirectory { // Must be called within a block passed to -perform(A)SynchronousFileAccessUsingBlock: NSURL *fileURL = [self fileURL]; return [[fileURL absoluteString] hasPrefix:NSHomeDirectory()]; } - (IBAction)doThing:(id)sender { [self performActivityWithSynchronousWaiting:YES usingBlock:^{ [self performSynchronousFileAccessUsingBlock:^{ 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]; if (!success) [self presentError:error]; } }]; } I'd really appreciate if the documentation spelled out exactly how NSDocument uses these methods. --Kyle Sluder _______________________________________________ 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