Statements in Replaced Method execute out of sequence - How?
Statements in Replaced Method execute out of sequence - How?
- Subject: Statements in Replaced Method execute out of sequence - How?
- From: Jerry Krinock <email@hidden>
- Date: Wed, 19 Aug 2009 11:48:14 -0700
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 (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