LoginSignup
15
16

More than 5 years have passed since last update.

一定時間、処理を非同期で待つメソッド

Posted at

通信処理など時間が掛かる処理を行いたいが、一瞬で完了してはUI的に困る。最低xx秒は処理の完了を待ってほしいときに以下のように呼び出す。
下の場合、A点の処理が一瞬で完了したとしても、最低0.8秒はB点の処理の実行は待機される。

sender.enabled = NO;
[NSObject perform:^(NSNotifyHandler done) {
    //A 通信などの処理
    [self hogeWithCompletion:^{
        done(^{
            //B 完了した時に行う動作
            NSLog(@"done");
            sender.enabled = YES;
        });
    }];
} waitUntil:0.8];

実装

実装には以前こちらで紹介されていたSTDeferredライブラリを利用させて頂きました。

NSObject+AsyncWaitUntil.h
typedef void(^NSNotifyHandler)(void (^completion)());

@interface NSObject (AsyncWaitUntil)
+ (void)perform:(void (^)(NSNotifyHandler done))task waitUntil:(NSTimeInterval)timeInterval;
@end
NSObject+AsyncWaitUntil.m

#import "NSObject+AsyncWaitUntil.h"

#import <STDeferred/STDeferred.h>

@implementation NSObject (AsyncWaitUntil)

+ (void)perform:(void (^)(NSNotifyHandler))task waitUntil:(NSTimeInterval)timeInterval
{
    NSAssert(task, @"NSNotifyHandler must be non-nil.");
    STDeferredBlock runTask = ^{
        STDeferred *deferred = [STDeferred deferred];
        NSNotifyHandler notify = ^(void (^completion)()) {
            [deferred resolve:completion];
        };
        task(notify);
        return deferred;
    };

    STDeferredBlock waitUntil = ^{
        STDeferred *deferred = [STDeferred deferred];
        int64_t delayInMilliSeconds = timeInterval * 1000;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInMilliSeconds * NSEC_PER_MSEC);
        dispatch_after(popTime, dispatch_get_current_queue(), ^(void){
            [deferred resolve:nil];
        });
        return deferred;
    };

    [[STDeferred when:runTask, waitUntil, nil] then:^(id resultObject) {
        id block = [resultObject objectAtIndex:0];
        if (![block isKindOfClass:[NSNull class]]) {
            void (^completion)() = block;
            completion();
        }
    }];
}
15
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
16