Maybe this is the Challenge of the Day. In debugging my undo grouping issue, I've replaced NSUndoManager's -beginUndoGrouping and - endUndoGrouping with methods that log whenever they're invoked. I suppose I could do this be setting breakpoints and debugging, but I've always trusted NSLog() more.

- (void)replacement_beginUndoGrouping {
    NSLog(@"WILL beginUndoGrouping for %@", self) ;
    NSInteger oldLevel = [self groupingLevel] ;
    NSInteger localSeqNum = gSeqNum ;
    [self replacement_beginUndoGrouping] ;
    NSLog(@" DID beginUndoGrouping level: %d->%d locSeqNum=%d",
          oldLevel, [self groupingLevel], localSeqNum) ;
    gSeqNum++ ;
}

(For those of you unfamiliar with Method Replacement, the above is NOT an infinite loop because [self replacement_beginUndoGrouping] invokes the ORIGINAL (Cocoa's) -beginUndoGrouping.)

Here's a snippet from Xcode's log while performing commands that invoke -beginUndoGrouping:

11:27:57.531 Test[804:10b] WILL beginUndoGrouping for <NSUndoManager: 0x170441d0> 11:27:57.547 Test[804:10b] WILL beginUndoGrouping for <NSUndoManager: 0x170441d0> 11:27:57.555 Test[804:10b] DID beginUndoGrouping level: 0->1 locSeqNum=5 11:27:57.556 Test[804:10b] DID beginUndoGrouping level: 0->2 locSeqNum=5

So, apparently this method is being invoked twice, but the second one starts before the first one is complete! At first I thought that this was just Xcode's console doing some of the lazy logging like Leopard's Console.app which drives me nuts. But the values of locSeqNum=5 and oldLevel=0 and the milliseconds say that these statements really ^are^ executing out of sequence. (The next time this executes, locSeqNum=7.) Furthermore, it says that this is all in the main thread, 10b and, yes, the same instance, 0x170441d0.

How can this happen?

This only happens about half the time. Other times, statements are executed in sequence.

Jerry

[1] http://developer.apple.com/SampleCode/MethodReplacement/index.html

Here's the entire implementation:

static NSInteger gSeqNum = 0 ;

@implementation NSUndoManager (Debug20090818)

+ (void)load {
    NSLog(@"%s is replacing methods", __PRETTY_FUNCTION__) ;
    Method originalMethod ;
    Method replacedMethod ;

originalMethod = class_getInstanceMethod(self, @selector(beginUndoGrouping)) ; replacedMethod = class_getInstanceMethod(self, @selector(replacement_beginUndoGrouping)) ;
    method_exchangeImplementations(originalMethod, replacedMethod) ;

originalMethod = class_getInstanceMethod(self, @selector(endUndoGrouping)) ; replacedMethod = class_getInstanceMethod(self, @selector(replacement_endUndoGrouping)) ;
    method_exchangeImplementations(originalMethod, replacedMethod) ;
}


- (void)replacement_beginUndoGrouping {
    NSLog(@"WILL beginUndoGrouping for %@", self) ;
    NSInteger oldLevel = [self groupingLevel] ;
    [self replacement_beginUndoGrouping] ;
NSLog(@" DID beginUndoGrouping level: %d->%d", oldLevel, [self groupingLevel]) ;
}

- (void)replacement_endUndoGrouping {
    NSLog(@"WILL --endUndoGrouping for %@", self) ;
    NSInteger oldLevel = [self groupingLevel] ;
    [self replacement_endUndoGrouping] ;
NSLog(@" DID --endUndoGrouping level: %d->%d", oldLevel, [self groupingLevel]) ;
}

@end

_______________________________________________

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