开发者

Confounding Cocoa problem — program hangs unless there’s an unrecognised method call

Bear with me, this one is hard to explain. I hope some hero out there knows what’s going on here. Some history needed;

One of my cocoa objects, “Ball” represents 开发者_如何学JAVAa small graphic. It only makes sense within a view. In some of the Ball’s methods, it asks the view to redraw. Most importantly, it asks the view to redraw whenever the Ball’s position parameter is set. This is achieved in the setter.

Here’s the mouthful, as suggested:

In View.m

- (void)mouseUp:(NSEvent *)theEvent {
    if (![runnerPath isEmpty]) {
        [walkPath removeAllPoints];
        [walkPath appendBezierPath:runnerPath];
        [runnerPath removeAllPoints];

        [[self held] setStep:0];
        [[self held] setPath:walkPath];
        [NSTimer scheduledTimerWithTimeInterval:.01 target:[self held] selector:@selector(pace) userInfo:nil repeats:YES];

        }
}

In Ball.m

 - (void)pace { 
    CGFloat juice = 10;
    BOOL loop = YES;

    while (loop) {
        if ([self step] == [[self path] elementCount]) {
            if ([[self timer] isValid]) {
                [[self timer] invalidate];
            }
            [[self path] removeAllPoints];
//          @throw([NSException exceptionWithName:@"test" reason:@"reason" userInfo:nil]);
        }

        if (loop) {
            CGFloat distance;
            NSPoint stepPoint;

            if ([[self path] elementCount] > 0) {
                NSPoint returnPoints[2];
                [[self path] elementAtIndex:[self step] associatedPoints:returnPoints];
                stepPoint = returnPoints[0];
                distance = pixelDistance([self position], stepPoint);
            }

            if (distance <= juice) {
                [self setPosition:stepPoint];
                if (distance < juice) {
                    juice -= distance;
                    loop = YES;
                    [self setStep:[self step]+1];
                } else {
                    loop = NO;
                }
            } else {            
                NSPoint cutPoint = moveAlongBetween([self position], stepPoint, juice);
                [self setPosition:cutPoint];

                loop = NO;
            }

        }
    }

}


could you also tell how you handle exceptions? since normally an unrecognized selector will end your program. Maybe you need an exception rather than an unrecognized selector. Try:

@throw([NSException exceptionWithName:@"test" reason:@"reason" userInfo:nil]);

If this would fix it as well, you're doing something after this code which freezes the app.

edit: thanks for the code update.

There's some weird stuff going on here! I'm not going to rewrite the whole thing, so here's some pointers:

  • first of all: you're looping inside some routine that is called from a timer loop. Is that intended? There is no way to pause execution within that while() loop, so it will happen in a blink anyway. You would need to keep some state information in the class. E.g. adding a loop counter every time pace is called.
  • second: if you start a timer, it will call your selector with the timer as an argument. So define the function as -(void)pace:(NSTimer*)timer, and use timer, not [self timer] (the latter will not be your timer anyway, if you don't assign it!)
  • third: you're firing 100 times a second. That is a lot, and presumably higher than the refresh rate of any device you're writing this for. I think 20/sec is enough.
  • fourth: to be sure, if you change it to -(void)pace:(NSTimer*)timer, don't forget to use @selector(pace:) (i.e. don't forget the :)

fix those things, and if it's still broken, update your question again and put in comment so we will know. Good luck!


Try calling

for (NSView *each in [self views]) {
    ...
}

I'm assuming that views is an array, so fast enumeration applies to it directly and there is no need to call allObjects.

A couple of other points.

  1. Have you set a Global breakpoint of objc_exception_throw? This will apply to all Xcode projects and is so useful I'm surprised it isn't set by default.
  2. You say you looked at the Console for errors. I take it, then, that you didn't set a breakpoint on the code and step into it to see exactly what is happening when your execution reaches that point? Have a look at the Xcode Debugging Guide
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜