0

説明されているパターンを使用しようとしています: Grand Central Dispatch and unit testing完了時にメイン キューを呼び出すユニット テスト async キューのパターン、主にhttps://github.com/AFNetworking/AFNetworking/issues/466# issuecomment-7917445 .

私の単体テストでは、いくつかのメソッドの非同期フローを「まっすぐにする」必要があります (fx AFNetworking は操作を要求します)。

これは、そのような「強制同期操作」のテスト内で使用するものです。

@property (nonatomic, assign) dispatch_semaphore_t semaphore;
// ...
- (void)runTestWithBlock:(void (^)(void))block {
    self.semaphore = dispatch_semaphore_create(0);

    block();

    while (dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_NOW))
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                             beforeDate:[NSDate dateWithTimeIntervalSinceNow:2]];

    dispatch_release(self.semaphore);
}

- (void)blockTestCompletedWithBlock:(void (^)(void))block {
    dispatch_semaphore_signal(self.semaphore);

    if (block) {
        block();
    }
}

fx dateWithTimeIntervalSinceNow:10を使用する場合、つまりゼロより大きい値 (引用された SO トピックや Github コメント状態など) を使用すると、テストで同等の余分な有害な遅延が発生します。...SinceNow:0...を設定すると、すべてのテストが遅延なく動作し、この0値に問題は見られません。

アップルのドキュメントは次のように述べています。

Runs the loop once, blocking for input in the specified mode until a given date.
If no input sources or timers are attached to the run loop, this method exits immediately and returns NO; otherwise, it returns after either the first input source is processed *or* limitDate is reached.

この「または」により、コードに悪影響を与えることなく 0 秒を使用できるかどうかを推測できます。

また、 runMode...メソッドのこのバリエーションを使用する代わりの方法、または引用されたリンクで説明されている問題を解決するためのまったく異なる解決策にも感謝します。

4

1 に答える 1

2

念のために言っておきますが、元の質問に対する答えはまだわかりません。

この問題の中間的な解決策 (非同期メソッドをテストするために GHUnit が使用するコードに着想を得たもの) は、[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeItervalSinceNow:0.05]のような短い時間間隔を使用することでした。

現在、次のループを使用しています。

while (dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_NOW))
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.05, YES);

遅延はなくなりました。

于 2012-10-24T10:24:57.257 に答える