Execution of Replaced Method Jumps back to top -- How??
Execution of Replaced Method Jumps back to top -- How??
- Subject: Execution of Replaced Method Jumps back to top -- How??
- From: Jerry Krinock <email@hidden>
- Date: Thu, 20 Aug 2009 08:54:49 -0700
[Re-sending this message with new details, and also because my thread
was hijacked yesterday.]
In debugging my undo grouping issue, I've replaced NSUndoManager's -
beginUndoGrouping and -endUndoGrouping with methods that log whenever
they're invoked.
- (void)replacement_beginUndoGrouping {
NSLog(@"WILL beginUndoGrouping for %@", self) ; // line 1
NSInteger oldLevel = [self groupingLevel] ;
NSInteger localSeqNum = gSeqNum ;
[self replacement_beginUndoGrouping] ; // line 4
NSLog(@" DID beginUndoGrouping level: %d->%d locSeqNum=%d",
oldLevel, [self groupingLevel], localSeqNum) ;
gSeqNum++ ;
}
(For those unfamiliar with Method Replacement [1], 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. Single-stepping in the Debugger shows the
same thing -- execution jumps from "line 4" back to "line 1". And
note that this is all in the main thread, 10b and, yes, the same
instance, 0x170441d0.
This only happens about 20% the time. Other times, statements execute
as expected.
One obvious possibility is that Method Replacement misbehaves and does
not invoke the replacement in this repeatable test case. How can this
happen?
Jerry
[1] http://developer.apple.com/SampleCode/MethodReplacement/index.html
Here's the entire implementation:
#import <objc/runtime.h>
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