0

内にカスタムビューがありNSPopoverます。ユーザーの入力に応じて変更する必要があり、ユーザーが最初に操作したときは変更されますが、次の回は再描画に失敗します。

NSLogメソッド内に を入れようとしましたが、-drawRect:通常の実行中に呼び出されません。メソッド内にブレークポイントをデバッグして配置しようとすると、通常どおり呼び出され、アプリは正常に動作します。

-setNeedsDisplay:再描画が必要になるたびに、view メソッドを明示的に呼び出します。なぜそれが違いを生む必要があるのか​​ わかりません。

ビューのステータスを更新するコードを次に示します。これらのメソッドはNSTextFieldデリゲート メソッドの一部であり-textDidChange:、ユーザーがポップオーバーに関連付けられたテキスト フィールドに何かを入力するたびに呼び出されることを確認しました。

[tokenCloud tokensToHighlight:[NSArray arrayWithObject:completeSuggestionString]];
tokenCloud.tokens = filteredTokens;
[tokenCloud setNeedsDisplay:YES];

ビューは一連の凹んだボタンです。最初の行はポップオーバー内のすべてのボタンのステータスを更新し、2 番目の行はボタンの追加または削除を更新します。最初に呼び出されたときにビューが適切に更新されるため、両方とも適切に機能します。tokenCloudボタンのステータスとそのプロパティのtokens両方が正しく更新されていることも確認しました。問題は、NSViewサブクラスtokenCloudが再描画されないため、変更が 2 回目に UI に反映されないことです。

ビューの draw メソッドは次のとおりです。

- (void)drawRect:(NSRect)rect {
    [self recalculateButtonLocations];
    NSLog(@"Redrawn");
}

にブレークポイントを配置すると、ビューを更新するたびにこのメソッドが正常に呼び出されます[self recalculateButtonLocations];。代わりに、アプリを通常どおり実行すると、ビューを 2 回目に更新したときにコンソールに何も記録されません。NSLogメソッドにを含めた場合も同じでrecalculateButtonLocations、2 回目は何もログに記録されず、メソッドが呼び出されないことを意味します。

4

1 に答える 1

0

EDIT2:将来の読者のために、この回答が低品質であることを申し訳ありません. そのほとんどは役に立たず、有用な部分はコメントとして作成する必要があります。私はそれを削除しますが、それは不誠実だと思います。この問題を抱えている人は、リンクされた回答でより多くの洞察を見つけることができます.

ボタンの描画方法によっては、サブビューの位置を変更するよりも、layoutSubviewsとを使用する方がよい場合があります。[編集: これが iOS ではなく Mac OS 用であるとは思わなかった。実際には layoutSubviews と同等であり、サブビューの配置を行う必要があるforがあります。]setNeedsLayoutdrawRectlayoutsetNeedsLayoutNSView

これ以上の情報がなければ、これ以上のアドバイスはできません。ただし、ブレークポイントで動作するという事実は興味深いものです。メソッド呼び出し行にブレークポイントを設定すると、より頻繁に呼び出されるようになる理由がわかりません。ブレークポイントがその上にあるかどうかに関係なく、メソッドを呼び出すかどうかに関係なく、このバグは上記のコードだけでは再現できないようです...この問題を引き起こしているのはあなたのコードの他の何かだと思います。


コードフローを変更するブレークポイントに関するいくつかの同様の質問。コードをスリープ状態にするか、ブレークポイント以外の方法で一時停止を追加して、動作するかどうかを確認してください。表示される場合は、以下の問題のいずれかを示している可能性があります。

コードの動作を変更するブレークポイントの最大の原因は、競合状態です。基本的には次のようになります。

Without breakpoints:
    make some asynchronous request
    do something with response
    ERROR because request hasn't responded yet

With breakpoints:
    send some asynchronous request
    wait for user to continue
    response arrived while waiting for the continue
    do something with response
    OK!

^ ブレークポイントのダーク アブソルをニートすると、プログラム フローが変更されます

私はこれを以前に見たことがありますが、私の推測では、システムが処理するにはイベントがポストされるのが速すぎます (実際に処理する必要があるのは、たとえば 1 秒間に 20 個を超えるキーイベントだけであるため)。usleep(100000) (スレッドを 1/10 秒一時停止する) のようなものを入れると、かなり役立つと思います。

^ CGKeyEvent Pasteing のDave DeLong は、ブレークポイントを使用していますが、使用していないわけではありません

通常、競合状態を示します。コードは、スレッド B が特定の状態に達する前に、スレッド A が何かを終了するか終了しないかに依存しています。

EXC_BAD_ACCESS からの ^bbum 、ただしブレークポイントを使用する場合は除く

于 2012-09-09T02:11:16.957 に答える