1

これは:

[self showInWindow:window];

delayこのコードによって呼び出されるもの:

[self performSelector:@selector(showInWindow:)
           withObject:window
           afterDelay:delay];

または私は方法を誤解していますか?

編集:私が抱えている問題は、メソッドshowInWindowが遅延後に呼び出されるが、のように動作することです[self showInWindow:nil]。なにか提案を?

4

2 に答える 2

2

はい、そう呼ばれます。(もちろん遅れてからです。)

ドキュメンテーションは、「セレクターを実行する」とはどういう意味かを実際には説明していませんが、それが意味することはまさにあなたが疑っていることです。

型メソッドの使用とメッセージの直接送信には小さな違いが 1 つありperformSelector:withObject:ます。それらは、オブジェクトが実際にオブジェクト (つまりid、Objective C オブジェクトへのポインター) である場合にのみ機能します。しかし、window明らかにオブジェクトです。

(厳密には、これは正しくありません。an と同じサイズidまたはそれより小さいものを渡すと、多くの場合、動作します。場合によっては、動作しない場合もあります。動作する場合もありますが、違法です。 , それは動作し、合法ですが, Apple はそれを強くお勧めします. それが良いアイデアであるケースはありません.は、NeXT 時代の Objective C で一般的に行われていたため、今日でも他の人の中で時折見られることがあります。)

performSelector:ファミリの詳細については、NSObject Protocol Referenceと SO question Using -performSelector: vs. just calling the method を参照してください。(afterDelay:バリアントに関する具体的な情報については、上記のリンク先のドキュメントを参照してください。)

後の編集から質問まで:

私が抱えている問題は、メソッドshowInWindowが遅延後に呼び出されるが、のように動作することです[self showInWindow:nil]。なにか提案を?

まず、パラメータが nil のように「振る舞う」のはどのような方法でしょうか。パラメータは実際には nil ですか? (実装にログを記録するだけshowInWindow:です。基本実装をオーバーライドしていない場合は、ベースを記録して呼び出すオーバーライドを追加するだけです。)

次に、実際に nil の場合、送信した時点で nil でしたperformSelector:withObject:afterDelay:か? もしそうなら、セレクターが送信されたとき、明らかにそれはまだ nil です。また、window実際にid他の型ではなく型であることを確認してください。(名前を共有するメンバー、プロパティ、グローバル、および/またはローカルwindowがある場合、どれを参照しているのか混乱する可能性があることに注意してください。これは問題の一般的な原因です。)

スケジュール時に実際には nil ではなく、到着時に nil である場合、発生する可能性がいくつかありますが、これらの 2 つのケースよりも可能性が低く、デバッグが難しいため、最初にそれらを除外しましょう。 .

于 2012-09-21T18:07:40.813 に答える
0

はい、それが機能します...ただし、実行には遅延よりも時間がかかる場合があることに注意してください。このメソッドは基本的NSTimerに現在のスレッドの実行ループ内に を設定するため、スレッドが負荷の高い作業でビジー状態になり、実行ループが戻ってくるまでの遅延よりも長くかかる場合、メソッドは後で実行されます。

于 2012-09-21T18:08:20.983 に答える