Неприятная проблема Какао - программа зависает, если нет неопознанного вызова метода - PullRequest
0 голосов
/ 27 июля 2010

Потерпи меня, это трудно объяснить. Я надеюсь, что какой-нибудь герой знает, что здесь происходит. Некоторая история нужна;

Один из моих объектов какао, «Шар», представляет собой небольшую графику. Это имеет смысл только в представлении. В некоторых методах Ball он запрашивает перерисовку представления. Самое главное, он просит перерисовать представление всякий раз, когда установлен параметр позиции Ball. Это достигается в сеттере.

Вот глоток, как и предлагалось:

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

        }
    }

}

Ответы [ 2 ]

1 голос
/ 27 июля 2010

Не могли бы вы также рассказать, как вы обрабатываете исключения? так как обычно нераспознанный селектор заканчивает вашу программу. Возможно, вам нужно исключение, а не нераспознанный селектор. Попробуйте:

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

Если это тоже исправит, то после этого кода вы делаете что-то, что останавливает приложение.

edit: спасибо за обновление кода.

Здесь происходят странные вещи! Я не собираюсь переписывать все это, так что вот несколько указателей:

  • прежде всего: вы зацикливаетесь внутри некоторой подпрограммы, которая вызывается из цикла таймера Это предназначено? В этом цикле while() нет способа приостановить выполнение, так что в любом случае это произойдет мгновенно. Вам нужно будет сохранить некоторую информацию о состоянии в классе. Например. добавление счетчика цикла каждый раз, когда вызывается pace.
  • секунда: если вы запустите таймер, он вызовет ваш селектор с таймером в качестве аргумента. Поэтому определите функцию как -(void)pace:(NSTimer*)timer и используйте timer, а не [self timer] (последний все равно не будет вашим таймером, если вы его не назначите!)
  • третье: вы стреляете 100 раз в секунду. Это много и, вероятно, выше, чем частота обновления любого устройства, для которого вы пишете это. Я думаю, что 20 / сек достаточно.
  • четвертый: чтобы быть уверенным, если вы измените его на -(void)pace:(NSTimer*)timer, не забудьте использовать @selector(pace:) (т.е. не забудьте :)

исправьте эти вещи, и если он все еще не работает, обновите ваш вопрос еще раз и оставьте комментарий, чтобы мы знали. Удачи!

1 голос
/ 27 июля 2010

Попробуйте позвонить

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

Я предполагаю, что views является массивом, поэтому быстрое перечисление применяется к нему напрямую, и нет необходимости вызывать allObjects.

Пара других пунктов.

  1. Вы установили глобальную точку останова objc_exception_throw? Это применимо ко всем проектам Xcode и настолько полезно, что я удивлен, что по умолчанию оно не установлено.
  2. Вы говорите, что смотрели на Консоль на наличие ошибок. Я так понимаю, что вы не установили точку останова в коде и не вошли в нее, чтобы точно увидеть, что происходит, когда ваше выполнение достигает этой точки? Взгляните на Руководство по отладке Xcode
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...