2013-02-17 24 views
5

bağlanana kadar yürütmeyi duraklat Web kitaplığına bağlanmayı işlemek için SocketRocket kitaplığını kullanıyorum. Sadece iyi bağlanır, ancak ilk önce WS bağlantısında beklemek zorunda olan bazı birim testleri çalıştırmaya çalışıyorum. WS'nin bağlı olduğunu bilmenin tek yolu delege yöntemiyle gerçekleştiğinden, bu işlemi senkronize etmekte zorlanıyorum. Ünite testlerimin 'setup yönteminin basitçe bir WS bağlantısı oluşturmasını ve tearDown kapamayı kapatmasını istiyorum.Websocket

Websocket sınıfım için iki tür bağlantı yöntemi uyguladım. İlk ikisi oldukça basit ve beklendiği gibi çalıştıklarını doğruladım. Sonuncusu, öncelikli olarak test amacıyla engellemeyi denemem. Çalışmayı başaramadım ve sadece sonsuza kadar beklemekle bitiyor, bu yüzden bunun benim için kavramsal bir yanlış anlama olduğuna inanıyorum.

Sanırım büyük sorum, bir temsilci için iade çağrısının beklenmesi için bir test vakasında yürütmeyi nasıl durdurabilirim? Test durumlarında ortaya çıkan problem, bütün testlerimi tamamlama blokunda yapamam - test metodu bunu bir başarı olarak görüyor ve programı sonlandırıyor.

- (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); 
    } 
} 

cevap

4

Semaforunuzun sinyal almasını beklerken, ana iş parçacığı engellenir, böylece hiçbir kod çalışmaz. Eğer kütüphaneniz runloop sistemiyle bütünleşiyorsa, runloop'u semaphore üzerinde beklemek yerine CFRunLoopRun() kullanarak çalıştırabilirsiniz. Hazır geri aramadan, CFRunLoopStop(CFRunLoopGetMain())'u kullanarak runloop'u durdurabilirsiniz.

+0

Evet! Bu mükemmel çalıştı ve yeni bir şey öğrendim. Teşekkürler! – joslinm