混淆Cocoa问题 - 程序挂起,除非有一个无法识别的方法调用

时间:2010-07-27 17:17:24

标签: objective-c cocoa unrecognized-selector

忍受我,这个很难解释。我希望那里的一些英雄知道这里发生了什么。需要一些历史;

我的一个可可物,“球”代表一个小图形。它只在视图中有意义。在Ball的一些方法中,它要求视图重绘。最重要的是,它会在设置Ball的位置参数时要求视图重绘。这是在setter中实现的。

这是满口的,如建议的那样:

在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];

        }
}

在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;
            }

        }
    }

}

2 个答案:

答案 0 :(得分:1)

尝试拨打

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

我假设views是一个数组,所以快速枚举直接应用于它,并且不需要调用allObjects。

其他几点。

  1. 您是否设置了objc_exception_throw的全局断点?这将适用于所有Xcode项目并且非常有用我很惊讶它没有默认设置。
  2. 您说您查看了控制台是否有错误。那么,我认为你没有在代码上设置断点并进入它以确切地看到当你的执行到达那个点时发生了什么?看看Xcode Debugging Guide

答案 1 :(得分:1)

你还可以告诉你如何处理异常?因为通常无法识别的选择器将结束您的程序。也许你需要一个例外而不是一个无法识别的选择器。尝试:

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

如果这样做也会解决问题,那么你会在这段代码之后做一些冻结应用程序的事情。

编辑:感谢代码更新。

这里有一些奇怪的东西!我不会重写整个事情,所以这里有一些指示:

  • 首先:你在一个从定时器循环调用的例程中循环。这是有意的吗?无法在while()循环内暂停执行,因此无论如何都会在闪烁中发生。你需要在课堂上保留一些状态信息。例如。每次调用pace时添加一个循环计数器。
  • 第二:如果你启动一个计时器,它将以定时器作为参数调用你的选择器。因此,将函数定义为-(void)pace:(NSTimer*)timer,并使用timer,而不是[self timer](如果您不指定,后者将不再是您的计时器!)
  • 第三:你每秒发射100次。这是很多,并且可能高于您为此编写的任何设备的刷新率。我认为20 /秒就足够了。
  • 第四:确定,如果您将其更改为-(void)pace:(NSTimer*)timer,请不要忘记使用@selector(pace:)(即不要忘记 :

解决这些问题,如果问题仍然存在,请再次更新您的问题并发表评论,以便我们知道。祝你好运!