88

数マイクロ秒後にコードを実行したいことがよくあります。今、私は次のようにそれを解決します:

- (void)someMethod
{
    // some code
}

この:

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

動作しますが、毎回新しいメソッドを作成する必要があります。これの代わりにブロックを使用することは可能ですか? 基本的に私は次のような方法を探しています:

[self performBlock:^{
    // some code
} afterDelay:0.1];

それは私にとって本当に役に立ちます。

4

6 に答える 6

107

これを行う組み込みの方法はありませんが、カテゴリを介して追加するのも悪くありません。

@implementation NSObject (PerformBlockAfterDelay)

- (void)performBlock:(void (^)(void))block 
          afterDelay:(NSTimeInterval)delay 
{
    block = [[block copy] autorelease];
    [self performSelector:@selector(fireBlockAfterDelay:) 
               withObject:block 
               afterDelay:delay];
}

- (void)fireBlockAfterDelay:(void (^)(void))block {
    block();
}

@end

基本的な実装については、Mike Ashの功績によるものです。

于 2010-10-24T03:38:22.630 に答える
41

これは、私が使用しているGCDに基づく簡単な手法です。

void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
      dispatch_get_current_queue(), block);
}

私は GCD の専門家ではありません。このソリューションに関するコメントに興味があります。

于 2011-01-20T16:01:24.887 に答える
23

別の方法 (おそらく多くの理由でこれを行う最悪の方法) は次のとおりです。

[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
    //do stuff here
}];
于 2011-11-26T23:19:27.830 に答える
16

特に長い遅延が必要な場合は、上記の解決策で問題なく機能します。私は@nickのアプローチを使用して大きな成功を収めました。

ただし、メイン ループの次の反復中にブロックを実行したいだけの場合は、次のようにしてさらに削減できます。

[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];

これは、afterDelay を 0.0f にして performSelector: を使用するのと似ています。

于 2011-07-23T20:54:10.997 に答える
1

この状況を処理する、優れた完全なカテゴリがここにあります。

https://gist.github.com/955123

于 2012-08-23T19:25:57.943 に答える