暂停执行直到Websocket连接

jos*_*inm 5 iphone concurrency grand-central-dispatch ios

我正在使用SocketRocket库来处理连接到Websocket.它连接得很好,但我正在尝试运行一些必须首先等待WS连接的单元测试.由于知道WS已连接的唯一方法是通过其委托方法,因此我无法使此进程同步.我希望我的单元测试setup方法只是创建一个WS连接,然后tearDown关闭它.

我已经为我的Websocket类实现了两种类型的连接方法.前两个是非常基本的,我已经验证它们按预期工作.最后一个是我试图阻止它主要用于测试目的.我无法让它工作,它最终等待永远,所以我认为这是一个概念上的误解.

我想我的大问题是如何在测试用例中停止执行以等待对委托的回复?测试用例中出现的问题是我不能在完成块中完成所有测试 - 测试方法看到这只是成功并结束程序.

- (void)connect
{
    DLog(@"Websocket is connecting now");
    [_socket open];
}


- (void)connectWithCompletion:(WebsocketConnection)completion
{
    DLog(@"Connecting now...");
    [_onConnectBlocksToRun addObject:^{
        completion(self.isConnected, self.socket);
    }];
    [_socket open];
}

- (bool)connectBlocking // XXX Doesn't work!
{
    sem = dispatch_semaphore_create(0);
    [_socket open];

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    return _isConnected;
}

#pragma mark - Socket rocket delegate
- (void)webSocketDidOpen:(SRWebSocket *)webSocket
{
    DLog(@"Websocket has opened");
    _isConnected = YES;
    _socket = webSocket;

    for (void(^block)() in _onConnectBlocksToRun) {
        block();
    }
    [_onConnectBlocksToRun removeAllObjects];

    if (sem) {
        dispatch_semaphore_signal(sem);
        dispatch_release(sem);
    }
}
Run Code Online (Sandbox Code Playgroud)

Sve*_*ven 4

当您等待信号量收到信号时,主线程被阻塞,因此根本没有代码可以运行。如果您的库与运行循环系统集成,您可以使用运行运行循环CFRunLoopRun()而不是等待信号量。从准备好的回调中,您可以使用 停止运行循环CFRunLoopStop( CFRunLoopGetMain() )