4

次のようなループを作成しようとしています。

while (TRUE){
  dispatch_after(...{
    <some action>
  });
}

viewDidLoad の後。アイデアは、dispatch_after を繰り返し繰り返すことです。dispatch_after は、アクションを実行する前に 2 秒間待機します。

これは機能しません - 画面が空白になるだけですか? ループに詰まってしまったのか…?

4

4 に答える 4

12

はい、gcd でそれを行うことができます。ただし、追加の c-function が 2 つ必要です。

static void dispatch_async_repeated_internal(dispatch_time_t firstPopTime, double intervalInSeconds, dispatch_queue_t queue, void(^work)(BOOL *stop)) {    
    __block BOOL shouldStop = NO;
    dispatch_time_t nextPopTime = dispatch_time(firstPopTime, (int64_t)(intervalInSeconds * NSEC_PER_SEC));
    dispatch_after(nextPopTime, queue, ^{
        work(&shouldStop);
        if(!shouldStop) {
            dispatch_async_repeated_internal(nextPopTime, intervalInSeconds, queue, work);
        }
    });
}

void dispatch_async_repeated(double intervalInSeconds, dispatch_queue_t queue, void(^work)(BOOL *stop)) {
    dispatch_time_t firstPopTime = dispatch_time(DISPATCH_TIME_NOW, intervalInSeconds * NSEC_PER_SEC);
    dispatch_async_repeated_internal(firstPopTime, intervalInSeconds, queue, work);
}

テスト済み!意図したとおりに動作します。

https://gist.github.com/4676773

于 2013-01-29T12:32:07.637 に答える
6

dispatch_after(...)いつ実行するようにスケジュールされていても、呼び出しはすぐに返されます。これは、ループがディスパッチするまでに 2 秒も待たないことを意味します。代わりに、互いに 2 秒間隔ではなく、2 秒後に発生する無限のキューを構築しています。

そうです、実行するブロックをどんどん追加するという無限ループに陥っています。2 秒ごとに何かを発生させたい場合は、繰り返し NSTimer を使用するか、ブロック dispatch_after をそれ自体の中に入れることができます (2 番目のブロックが最初のブロックの 2 秒後に実行されるように)。

于 2012-07-13T06:18:14.947 に答える
1

たとえば、タグが更新されたかどうかを確認するために遅延後に非同期タスクを実行してから終了する場合は、次のコードを使用できます。

typedef void (^RepeatCompletionHandler)(BOOL isRepeat);

typedef void (^RepeatBlock)(RepeatCompletionHandler completionHandler);

- (void)dispatchRepeat:(int)seconds withBlock:(RepeatBlock)block {

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^() {
                       block(^(BOOL isRepeat) {
                           if (isRepeat) {
                               return [self dispatchRepeat:seconds withBlock:block];
                           }
                       });
                   });

}

例えば:

[self dispatchRepeat:5 withBlock:^(RepeatCompletionHandler completionHandler) {

    [tagsService getTagValueForTagName:TagName value:^(NSString *tagValue) {
        if (![TagValue isEqualToString:tagValue]) {
            return completionHandler(YES);
        }
        completionHandler(NO);
    }];

}];
于 2016-02-19T01:35:04.353 に答える