0

我慢してください、これは説明するのが難しいです。ここで何が起こっているのかを知っているヒーローがいるといいのですが。いくつかの履歴が必要です。

私のココア オブジェクトの 1 つである「ボール」は、小さなグラフィックを表しています。ビュー内でのみ意味があります。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];

        }
}

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

        }
    }

}
4

2 に答える 2

1

電話してみる

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

私はそれviewsが配列であると仮定しているので、高速な列挙が直接適用され、allObjects を呼び出す必要はありません。

他のいくつかのポイント。

  1. objc_exception_throw のグローバル ブレークポイントを設定しましたか? これはすべての Xcode プロジェクトに適用され、非常に便利です。デフォルトで設定されていないことに驚いています。
  2. コンソールでエラーを確認したとします。では、コードにブレークポイントを設定してブレークポイントにステップ インし、実行がそのポイントに到達したときに何が起こっているかを正確に確認していないと思いますか? Xcodeデバッグガイドを見てください
于 2010-07-27T17:23:36.513 に答える
1

例外の処理方法も教えていただけますか? 通常、認識されないセレクターはプログラムを終了するためです。認識されていないセレクターではなく、例外が必要な場合があります。試す:

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

これでも修正される場合は、このコードの後に​​アプリをフリーズさせる何かを行っています。

編集:コードの更新をありがとう。

ここで奇妙なことが起こっています!すべてを書き直すつもりはないので、ここにいくつかのポインタを示します。

  • まず第一に、タイマーループから呼び出されるルーチン内でループしています。それは意図したものですか?そのwhile()ループ内で実行を一時停止する方法はないため、とにかく瞬く間に発生します。クラスにいくつかの状態情報を保持する必要があります。paceたとえば、呼び出されるたびにループカウンターを追加します。
  • 2 番目: タイマーを開始すると、タイマーを引数としてセレクターが呼び出されます。したがって、関数を , として定義し、, not-(void)pace:(NSTimer*)timerを使用します(後者は、割り当てないとタイマーにはなりません!)timer[self timer]
  • 3 番目: 1 秒間に 100 回発砲しています。これはかなりの量であり、おそらく、これを書いているデバイスのリフレッシュ レートよりも高いでしょう。20/秒で十分だと思います。
  • 4 番目: に変更する場合は、必ず-(void)pace:(NSTimer*)timer使用することを忘れないでください@selector(pace:)(つまり、を忘れないでください:) 。

それらを修正し、それでも問題が解決しない場合は、質問を再度更新してコメントを記入してください。幸運を!

于 2010-07-27T17:25:29.183 に答える