On 2011 Aug 04, at 08:30, Kevin Perry wrote:

> What Ken said.

OK, I'm back.  Had to fork my project since Block_copy()/release() is not 
available in 10.5 SDK.  But it works now.  See code below.

> Also, it might be more convenient to use NSBlockOperation or 
> -addOperationWithBlock so the function parameters (including the completion 
> handler) are all captured correctly for you automatically. It's a lot more 
> convenient than stashing things in an NSDictionary.

Thank you, for my next project.  But in this project I've got a home-made main 
operation queue which I wrote back in the 10.5 days.

> Finally, I misspoke about the application blocking…

That was fine; you were using the word "block" in a broader sense - not just as 
in threads.

> Also, what I said about other applications blocking trying to get sole access 
> to the file via file coordination is still true.

If more changes are known to be coming in a few seconds, I think they should 
wait.

** One little surprise.  After dequeueing the save operation, I kind of thought 
that I could invoke the new synchronous saving method 
saveToURL:::completionHandler:.  However, this does not save and apparently 
does not run the completion handler properly because I still get the 
hanging/blocking in -[NSDocument performAsynchronousFileAccessUsingBlock:].  
But if I invoke the old async -saveToURL:::error: method and invoke the 
completion handler block "manually", it works fine.  Here…

/*!
 @brief    Real saving method, invoked when a save operation is
 dequeued to do the actual work.
 */
- (void)reallySaveToURL:(NSURL *)url
                 ofType:(NSString *)typeName
       forSaveOperation:(NSSaveOperationType)saveOperation
      completionHandler:(void (^)(NSError *errorOrNil))completionHandler {
    [self prepareForSaveOperation:saveOperation] ;
        
#if 0
#warning Using fancy new async saveToURL::::.  Doesn't work.
    [super saveToURL:url
              ofType:typeName
    forSaveOperation:saveOperation
   completionHandler:completionHandler] ;
    // Still hangs even if the following is commented out.
    Block_release(completionHandler) ;
#else
#warning Invoking completionHandler manually.  This works.
    NSError* error = nil ;
    BOOL ok = [super saveToURL:url
                        ofType:typeName
              forSaveOperation:saveOperation
                         error:&error] ;
    completionHandler(error) ;
    Block_release(completionHandler) ;
    if (error && ok) {
        NSLog(@"Internal Error 923-0284 %@", error) ;
    }
#endif
}    


/*!
 @brief    Override of new asynchronous saving method invoked by Cocoa
 when running in Mac OS X 10.7 or later.
 
 @details  
 
 * Case  saveOperation  maenQueue  Cancellable?  Action
 * ----  -------------  ---------  ------------  --------------------
 *   1      not AIP         X           X        Add to queue
 *   2        AIP       not busy        X        Add to (empty) queue
 *   3        AIP         busy        Yes        Cancel the Save
 *   4        AIP         busy         No        Add to (busy) queue
 
 AIP = Auto Save In Place
 X = don't care
 */
- (void)saveToURL:(NSURL *)url
           ofType:(NSString *)typeName
 forSaveOperation:(NSSaveOperationType)saveOperation
completionHandler:(void (^)(NSError *errorOrNil))completionHandler {
    if (saveOperation == NSAutosaveInPlaceOperation) {
        // Case 2, 3 or 4
        if ([[[SSYOperationQueue maenQueue] operations] count] != 0) {
            // Case 3 or 4  (busy)
              if ([self autosavingIsImplicitlyCancellable]) {
                // Case 3.  Cancel the Save
                completionHandler([NSError errorWithDomain:NSCocoaErrorDomain
                                                      code:NSUserCancelledError
                                                  userInfo:nil]) ;
                /*DB?Line*/ NSLog(@"133955: Cancelling Save") ;
                return ;
            }
            else {
                // Case 4.  Add to (busy) queue
            }
        }
        else {
            // Case 2.  Add to (empty) queue
        }
    }
    else {
        // Case 1.  Add to queue
    }
    
    // Note that we arrive here either in Case 1, 2 or 4.
    // In Case 2, and maybe Case 1, instead of adding the save
    // operation to our queue, we could invoke -reallySaveToURL::::
    // synchronously.  However we don't do that because the usual
    // notification sent when work is done, which we need for
    // housekeeping, would not be sent, and also it would be
    // extra code and an extra branch which means more testing
    // and bug possibilities.
    
    <snip>
    … Code here adds operation to my SSYOperationQueue, kind of a 
    … cheesy main operation queue which I wrote back in the Leopard days
    … for this project.  It also copies the completionHandler block…
    [info setValue:Block_copy(completionHandler) forKey:kCompletionHandler] ;
    … When operation is dequeued, it invokes reallySaveToURL::::.
    </snip>
}

_______________________________________________

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