メソッド呼び出しを1秒間遅延させるにはどうすればよいですか?


164

メソッド呼び出しを1秒間遅延させる簡単な方法はありますか?

私が持っているUIImageViewタッチイベントに反応することを。タッチが検出されると、アプリでアニメーションが発生します。1秒後、別のメソッドを呼び出します。この場合、animationDidStopセレクターを使用できません。


それを行うには、いくつかの方法は、ミリ秒数のためのプログラム/スレッドを一時停止する)(そのうちの一つは、単に睡眠を使用するかもしれないが、確かにあります、私はあなたがで達成しようとしている正確に何を教えたいかもしれないと思いますそれをやって?つまり、あなたの実際の問題は何ですか?メソッドの呼び出しを遅らせるという考えは「解決策」のように思えます。正直に言うとあまりにも良さそうに聞こえません。だから、あなたが考えているシナリオについてもっと教えてください。
なし

回答:


254
performSelector:withObject:afterDelay:

ドキュメント参照


7
これが正解です。参照してくださいdeveloper.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/...を
損なう

呼び出されるメソッドの戻り値で何かをする方法はありますか?または、情報を取得したい場合は、パラメータを変更するように設定する必要がありますか?
ゴードングスタフソン

誰かがスケジュールされた呼び出しをキャンセルする方法に興味がある場合:[NSObject cancelPreviousPerformRequestsWithTarget:yourTarget selector:aSelector object:anArgument];
2014

192

ブロックを使用することもできます

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [object method]; 
});

ほとんどの場合、dispatch_get_main_queueを使用しますが、メソッドにUIがない場合は、グローバルキューを使用できます

編集:

Swift 3バージョン:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    object.method()
}

同様に、DispatchQueue.global().asyncAfter(...良いオプションかもしれません。


ストレートCとObjCを混在させる場合、このソリューションはperformSelectorよりも簡単であることがわかりました
Paul Slocum

1
残念ながら、dispatch_get_current_queueはiOS6以降廃止されました
chrisben

3
dispatch_get_current_queueの代わりにdispatch_get_main_queueを使用するように更新
mcfedr

2
Xcodeはこれを自動入力します。入力dispatch_afterを開始して
Enterキー

1
特に今、Xcode dispatch_afterはを入力するとこれをオートコンプリートします。これは実際には非常に簡単な方法です。さらに、呼び出すメソッドにプロパティを渡すことができるので、すばらしいです。
Erik van der Neut 2015

128

最善の方法は次のとおりです。

[self performSelector:@selector(YourFunctionName) 
           withObject:(can be Self or Object from other Classes) 
           afterDelay:(Time Of Delay)];

withObjectパラメータとしてnilを渡すこともできます。

例:

[self performSelector:@selector(subscribe) withObject:self afterDelay:3.0 ];

3
なぜあなたは自分自身を自分自身に渡すのですか?
Eric

2
そして、なぜ引数をとらないメソッドに変数を渡すのでしょうか?
hellozimi 2014年

23

すでに多くの答えがあり、それらはすべて正しいです。使用したい場合は、右下の(要素を選択できる)dispatch_after内に含まれているスニペットを探しているはずCode Snippet LibraryですUI

ここに画像の説明を入力してください

したがって、コードでディスパッチを記述することにより、このスニペットを呼び出すだけです。

ここに画像の説明を入力してください


16

これを行うには、0.1秒のdelayメソッドが次のコードを呼び出した後に、performセレクターを使用できます。

[self performSelector:@selector(InsertView)  withObject:nil afterDelay:0.1]; 

9

あなたもすることができます:

[UIView animateWithDuration:1.0
                 animations:^{ self.view.alpha = 1.1; /* Some fake chages */ }
                 completion:^(BOOL finished)
{
    NSLog(@"A second lapsed.");
}];

この場合、アニメーションを機能させるために、ビューにいくつかの変更を加える必要があります。確かにハッキーですが、ブロックベースのものが大好きです。または、以下の@mcfedrの回答をまとめてください。


waitFor(1.0, ^
{
    NSLog(@"A second lapsed");
});

typedef void (^WaitCompletionBlock)();
void waitFor(NSTimeInterval duration, WaitCompletionBlock completion)
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^
    { completion(); });
}

確かではありませんが、最初に提案するオプションには、UIの一部でのユーザーインタラクションのブロックなど、ユーザーが知っておくべき副作用があると思います。私の直感は、それがまた不必要なCPUまたは他のリソースの浪費を引き起こすだろうということですが、私はチェックしていません。
ビョルンロッシュ

8

あなたはこれを行うことができます

[self performSelector:@selector(MethodToExecute) withObject:nil afterDelay:1.0 ];

4

Swift 2.x

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
 dispatch_after(delayTime, dispatch_get_main_queue()) {
 print("do some work")
}

Swift 3.x-&-Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    print("do some work")
}

または渡す escaping closure

func delay(seconds: Double, completion: @escaping()-> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds, execute: completion)
}

1

チェックされたソリューションからのSwift 3ソリューションがあります:

self.perform(#selector(self.targetMethod), with: self, afterDelay: 1.0)

そして方法があります

@objc fileprivate func targetMethod(){

}


-34

注:これにより、1つのメソッドだけでなく、スレッド全体が一時停止します。
メソッドを呼び出す直前に、スリープ/待機/停止を1000ミリ秒呼び出しますか?

Sleep(1000); // does nothing the next 1000 mSek

Methodcall(params); // now do the real thing

編集:上記の回答は、一般的な質問「メソッドの呼び出しを1秒間遅らせるにはどうすればよいですか?」に適用されます。これは、回答時に質問された質問です(元の質問から7分以内に回答が与えられた場合:- ))。当時、言語に関する情報は提供されていなかったので、クラスの欠如やスリープi XCodeの適切な使用方法についての愚痴をやめてください...


現在のスレッドでのみ、他のスレッドは引き続き実行されます。
マルクシャル

4
もう。これが数回反対投票された理由がわかりますが、一体誰が-27でこれを見て、別の人が必要だと判断したのですか?-3か何かで要点がわかりません。答えを編集して、「これでスレッド全体が一時停止します」などと言って、人々に反対票を投じるのではなく、なぜですか?
Albert Renshaw

では、スレッド全体を一時停止したい場合はどうでしょうか。まともな警告が表示される場合は、有効なオプションのようです。
Departamento B

@AlbertRenshaw私はあなたに完全に同意します。私はここにいて、その35ダウンし、私は彼をあきらめました 評判の低いユーザーへの攻撃がひどいのではないでしょうか。誰も編集や何かを指定することはありません。今日は本当に溺死したという答えを1つ見ました。その人がした唯一の間違いは、彼/彼女が客観的なC言語で迅速な質問の下で答えたことです。それが大きな間違いである場合、私は客観的なcの質問の下で非常に多くの迅速な答えを示したいと思います。
soorej babu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.