how to set "smart" breakpoint in Xcode when method returns a specific value?
I have a method which returns a bool
value, with several exit points.
However, it does not seem to work correctly, so I would like to set an automatic breakpoint to see when it returns a YES value, so I can check all the variables and calculations in the debugger.
I would like to stop the debugger whenever a YES
value is returned.
I have a similar smart breakpoint set for objc_exception_throw
, so I know it's possible, I am just not sure how.
(In case it helps anyone, the way you can set the exception breakpoint: in the Breakpoints window (Run -> Show -> Breakpoints) enter objc_exception_throw
as "Breakpoint", and libobjc.A.dylib
as "Location")
EDIT: the specific code I would like to use it for:
- (BOOL)collisionOccured {
// Assumption: helicopter is of square shape (collision calculated by radius), walls are rectangles
// This approach is based on the solution seen here: http://sta开发者_JAVA百科ckoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection/402010#402010
float helicopterImageWidth = [helicopter texture].contentSize.width;
float wallImageWidth = [[walls lastObject] texture].contentSize.width;
float wallImageHeight = [[walls lastObject] texture].contentSize.height;
float helicopterCollisionRadius = helicopterImageWidth * 0.4f;
CGPoint helicopterPosition = helicopter.position;
int numWalls = [walls count];
for (int i = 0; i < numWalls; i++) {
CCSprite *wall = [walls objectAtIndex:i];
if ([wall numberOfRunningActions] == 0) {
// The wall is not moving, we can skip checking it.
continue;
}
CGPoint wallPosition = wall.position;
float helicopterDistanceX = abs(helicopterPosition.x - wallPosition.x - wallImageWidth/2);
float helicopterDistanceY = abs(helicopterPosition.y - wallPosition.y - wallImageHeight/2);
if (helicopterDistanceX > (wallImageWidth/2 + helicopterCollisionRadius)) { return NO; }
if (helicopterDistanceY > (wallImageHeight/2 + helicopterCollisionRadius)) { return NO; }
if (helicopterDistanceX <= (wallImageWidth/2)) { return YES; }
if (helicopterDistanceY <= (wallImageHeight/2)) { return YES; }
float cornerDistance_sq = powf((helicopterDistanceX - wallImageWidth/2), 2) +
powf((helicopterDistanceY - wallImageHeight/2), 2);
return (cornerDistance_sq <= powf(helicopterCollisionRadius, 2));
}
// this should not occur
return NO;
}
This method is called via
- (void)update:(ccTime)delta {
if ([self collisionOccured]) {
NSLog(@"A collision occured");
}
}
The problem is that the update method takes delta
(time passed) as argument, so I can't check what's happening frame by frame -- whenever I continue the execution, I am presented with a different scene.
(I am using cocos2d in the code)
You can set conditional breakpoints. With a slight tweak to update:
- (void)update:(ccTime)delta {
BOOL collided = [self collisionOccured];
if (collided) {
NSLog(@"A collision occured");
}
}
you can set a breakpoint as normal after the BOOL
's assignment (i.e. on the if
line), then right-click on the blue breakpoint arrow and select "Show Message Bubble", and add collided
as the Condition. The extra variable should get optimized away in Release build mode.
If you're using a local return variable:
- (BOOL)someMethod {
BOOL ret = NO;
if (something) {
ret = YES;
} else if (something_else) {
ret = YES;
}
// ... and so on
return ret;
}
You can just set a watch point on ret
Otherwise, you're probably stuck with stepping through the code—hopefully some clever combination of conditional breakpoints will help you not have to break on every invocation. Setting a method breakpoint like you do with objc_exception_throw
wouldn't work, because it will stop on every invocation, and breaking on the return value at the calling site is too late to figure out how you got there.
If you can post the code, we may be able to give more specific help as to a debugging strategy. Good luck. :-)
精彩评论