765

を使用するのと同じように、遅延後にプリミティブパラメータを使用してブロックを呼び出す方法はありますが、 //のperformSelector:withObject:afterDelay:ような引数を使用しますか?intdoublefloat

4

20 に答える 20

1209

を探していると思いますdispatch_after()。ブロックがパラメーターを受け入れないようにする必要がありますが、代わりにブロックがローカル スコープからそれらの変数を取得できるようにすることができます。

int parameter1 = 12;
float parameter2 = 144.1;

// Delay execution of my block for 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    NSLog(@"parameter1: %d parameter2: %f", parameter1, parameter2);
});

詳細: https://developer.apple.com/documentation/dispatch/1452876-dispatch_after

于 2010-11-09T22:28:01.393 に答える
524

dispatch_after後でブロックを呼び出すために使用できます。Xcode で、次のように入力dispatch_afterを開始Enterし、オートコンプリートを押します。

ここに画像の説明を入力

「引数」として 2 つの float を使用した例を次に示します。どのタイプのマクロにも依存する必要はなく、コードの意図は非常に明確です。

スイフト 3、スイフト 4

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    print("Sum of times: \(time1 + time2)")
}

スイフト2

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
        println("Sum of times: \(time1 + time2)")
}

オブジェクティブ C

CGFloat time1 = 3.49;
CGFloat time2 = 8.13;

// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    CGFloat newTime = time1 + time2;
    NSLog(@"New time: %f", newTime);
});
于 2011-10-24T03:01:27.313 に答える
205

Xcode の組み込みコード スニペット ライブラリを使用するのはどうですか?

ここに画像の説明を入力

スイフトの更新:

多くの賛成票が、この回答を更新するきっかけになりました。

組み込みの Xcode コード スニペット ライブラリには、言語dispatch_afterのみがあります。objective-cユーザーは、独自のカスタム コード スニペットを作成することもできますSwift

これを Xcode で記述します。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(<#delayInSeconds#> * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
        <#code to be executed after a specified delay#>
    })

このコードをコード スニペット ライブラリ領域にドラッグ アンド ドロップします。 ここに画像の説明を入力

コード スニペット リストの一番下に、 という名前の新しいエンティティがありMy Code Snippetます。これをタイトルに編集します。Xcode に入力する際の提案については、Completion Shortcut.

詳細については、CreatingaCustomCodeSnippet を参照してください。

Swift 3 を更新する

このコードをコード スニペット ライブラリ領域にドラッグ アンド ドロップします。

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(<#delayInSeconds#>)) {
    <#code to be executed after a specified delay#>
}
于 2014-05-23T06:19:01.217 に答える
59

Jaime Cham の回答を拡張して、以下のように NSObject+Blocks カテゴリを作成しました。performSelector:これらのメソッドは、既存のNSObject メソッドとよりよく一致していると感じました

NSObject+Blocks.h

#import <Foundation/Foundation.h>

@interface NSObject (Blocks)

- (void)performBlock:(void (^)())block afterDelay:(NSTimeInterval)delay;

@end

NSObject+Blocks.m

#import "NSObject+Blocks.h"

@implementation NSObject (Blocks)

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

- (void)performBlock:(void (^)())block afterDelay:(NSTimeInterval)delay
{
    void (^block_)() = [block copy]; // autorelease this if you're not using ARC
    [self performSelector:@selector(performBlock:) withObject:block_ afterDelay:delay];
}

@end

そして次のように使用します:

[anyObject performBlock:^{
    [anotherObject doYourThings:stuff];
} afterDelay:0.15];
于 2013-02-12T10:15:01.157 に答える
21

Swift の場合、dispatch_afterメソッドを使用して、特別なものではないグローバル関数を作成しました。読みやすく使いやすいので、私はこれがもっと好きです:

func performBlock(block:() -> Void, afterDelay delay:NSTimeInterval){
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), block)
}

次のように使用できます。

performBlock({ () -> Void in
    // Perform actions
}, afterDelay: 0.3)
于 2015-04-08T09:30:21.260 に答える
21

おそらく、どこかのクラス(「Util」など)、またはオブジェクトのカテゴリで、GCDを通過するよりも簡単です。

+ (void)runBlock:(void (^)())block
{
    block();
}
+ (void)runAfterDelay:(CGFloat)delay block:(void (^)())block 
{
    void (^block_)() = [[block copy] autorelease];
    [self performSelector:@selector(runBlock:) withObject:block_ afterDelay:delay];
}

使用するには:

[Util runAfterDelay:2 block:^{
    NSLog(@"two seconds later!");
}];
于 2011-09-27T08:51:24.517 に答える
5

迷惑な GCD 呼び出しを何度も行うのを防ぐための便利なヘルパーを次に示します。

public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
    let dispatchTime = DispatchTime.now() + seconds
    dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}

public enum DispatchLevel {
    case main, userInteractive, userInitiated, utility, background
    var dispatchQueue: DispatchQueue {
        switch self {
        case .main:                 return DispatchQueue.main
        case .userInteractive:      return DispatchQueue.global(qos: .userInteractive)
        case .userInitiated:        return DispatchQueue.global(qos: .userInitiated)
        case .utility:              return DispatchQueue.global(qos: .utility)
        case .background:           return DispatchQueue.global(qos: .background)
        }
    }
}

次のように、メイン スレッドでコードを遅らせるだけです。

delay(bySeconds: 1.5) { 
    // delayed code
}

コードを別のスレッドに遅らせたい場合:

delay(bySeconds: 1.5, dispatchLevel: .background) { 
    // delayed code that will run on background thread
}

より便利な機能も備えたフレームワークが必要な場合は、 HandySwiftをチェックしてください。Carthage を介してプロジェクトに追加し、上記の例とまったく同じように使用できます。

import HandySwift    

delay(bySeconds: 1.5) { 
    // delayed code
}
于 2016-06-09T16:56:04.040 に答える
5

遅延後に作業をキューに入れる Swift 3 の方法を次に示します。

DispatchQueue.main.asyncAfter(
  DispatchTime.now() + DispatchTimeInterval.seconds(2)) {
    // do work
}
于 2016-08-02T07:23:46.107 に答える
4

BlocksKit フレームワークには素晴らしいものがあります。

ブロックキット

(そしてクラス)

BBlocksKit.m

于 2012-09-14T22:31:13.260 に答える
4

Cmd + Shift + L を押して、Xcode 組み込みコード スニペット ライブラリを表示します。

ここに画像の説明を入力

ディスパッチを探してから、コードにドラッグ アンド ドロップするだけです。

于 2021-07-01T09:32:58.900 に答える
4

Swift 3 では、単に DispatchQueue.main.asyncAfter 関数を使用して、「n」秒の遅延後に任意の関数またはアクションをトリガーできます。このコードでは、1 秒後に遅延を設定しています。この関数の本体内で、1 秒の遅延後にトリガーされる任意の関数を呼び出します。

let when = DispatchTime.now() + 1
DispatchQueue.main.asyncAfter(deadline: when) {

    // Trigger the function/action after the delay of 1Sec

}
于 2017-05-17T11:09:45.977 に答える
1

独自のクラスで引数をラップするか、プリミティブ型で渡す必要のないメソッドでメソッド呼び出しをラップすることができます。次に、遅延後にそのメソッドを呼び出し、そのメソッド内で実行したいセレクターを実行します。

于 2010-11-09T22:23:58.237 に答える