2013-02-17 56 views
5

कनेक्ट नहीं करता है तब तक निष्पादन रोकें मैं वेबसाइट पर कनेक्ट करने के लिए SocketRocket लाइब्रेरी का उपयोग कर रहा हूं। यह ठीक जुड़ा है, लेकिन मैं कुछ यूनिट परीक्षण चलाने की कोशिश कर रहा हूं जिन्हें पहले डब्ल्यूएस कनेक्टिंग पर इंतजार करना है। चूंकि डब्ल्यूएस कनेक्ट है, यह जानने का एकमात्र तरीका है कि इस प्रतिनिधि प्रक्रिया के माध्यम से, मुझे इस प्रक्रिया को तुल्यकालिक बनाने में परेशानी हो रही है। मैं चाहता हूं कि मेरा यूनिट परीक्षण 'setup विधि केवल एक डब्ल्यूएस कनेक्शन बनाने के लिए और फिर tearDown बंद करें।जब तक वेबसाइट्स

मैंने अपनी वेबसाइट की कक्षा के लिए दो प्रकार के कनेक्शन विधियों को लागू किया है। पहले दो बहुत ही बुनियादी हैं और मैंने सत्यापित किया है कि वे अपेक्षित काम करते हैं। अंतिम रूप से परीक्षण उद्देश्यों के लिए इसे मुख्य रूप से अवरुद्ध करने का मेरा प्रयास है। मैं इसे काम करने में सक्षम नहीं हूं और यह हमेशा के लिए इंतजार कर रहा है, इसलिए मेरा मानना ​​है कि यह मेरे हिस्से पर एक वैचारिक गलतफहमी है।

मुझे लगता है कि मेरा बड़ा सवाल यह है कि मैं किसी प्रतिनिधि को रिटर्न कॉल पर इंतजार करने के लिए टेस्ट केस में निष्पादन कैसे रोक सकता हूं? परीक्षण मामलों में उत्पन्न होने वाली समस्या यह है कि मैं पूरा होने वाले ब्लॉक में अपने सभी परीक्षण नहीं कर सकता - परीक्षण विधि इसे सफलता के रूप में देखती है और कार्यक्रम को समाप्त करती है।

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

उत्तर

4

आप के लिए अपने सेमाफोर का संकेत करने के लिए मुख्य थ्रेड अवरुद्ध है ताकि कोई कोड बिल्कुल चला सकते हैं इंतज़ार कर रहे हैं है। यदि आपकी लाइब्रेरी रनलोप सिस्टम के साथ एकीकृत करती है तो आप अपने सेमफोर पर प्रतीक्षा करने के बजाय CFRunLoopRun() का उपयोग करके रनलोप चला सकते हैं। अपने तैयार कॉलबैक से आप CFRunLoopStop(CFRunLoopGetMain()) का उपयोग कर रनलोप को रोक सकते हैं।

+0

हाँ !! यह पूरी तरह से काम किया और मैंने कुछ नया सीखा। धन्यवाद! – joslinm