2013-03-26 64 views
3

我目前正在嘗試在後臺線程中運行我的整個網絡東西,因爲當前服務器無法訪問(即)時,它阻塞主線程。在後臺運行NSStream線程

我目前通過以下代碼創建網絡連接。有一種簡單的方法在新的後臺線程中運行它嗎?

如何將接收到的消息返回給主線程?我怎樣才能通過後臺線程發送消息?

CFReadStreamRef readStream; 
CFWriteStreamRef writeStream; 
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ipAdress, port, &readStream, &writeStream); 
inputStream = (__bridge NSInputStream *)readStream; 
outputStream = (__bridge NSOutputStream *)writeStream; 
[inputStream setDelegate:self]; 
[outputStream setDelegate:self]; 
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

[inputStream open]; 
[outputStream open]; 
+0

而不輪詢流,是否有一個特定的問題,你認爲你可以通過推到後臺線程解決? – 2013-03-26 08:07:38

+0

嗨,我不確定,因爲我沒有真正進入線程和合作。在Objective-C中。我願意接受任何其他建議。有沒有什麼好的教程可以解決這個問題?謝謝! – 2013-03-26 08:10:01

+0

*問題是什麼?你爲什麼要使用一個單獨的線程? – 2013-03-26 08:15:18

回答

4

here是一個教程,完全按照你所說的去做。雖然它更側重於音頻流,但其原理完全相同(即在產生工作者線程,與父線程交談等方面)。

這個想法很簡單..您創建一個新線程並讓它處理流式工作,然後您使用屬於您剛創建的線程的運行循環安排流式閱讀器。該流將有回調,當ceratain事件發生時(即你得到一些數據,連接超時等等)會被觸發。在回調方法中,你可以通過主線程(這是處理UI的線程) 。

下面是一些代碼,以指向您在正確的方向,但如果你從上面的教程下載code和貫徹..你會得到它:由於您使用的是runloop

// create a new thread 
internalThread = 
       [[NSThread alloc] 
        initWithTarget:self 
        selector:@selector(startInternal) 
        object:nil]; 
      [internalThread start]; 

// creating a stream inside the 'startInternal' thread* 
stream = CFReadStreamCreateForHTTPRequest(NULL, message); 

// open stream 
CFReadStreamOpen(stream) 

// set callback functions 
// ie say: if there are bites available in the stream, fire a callback etc 
CFStreamClientContext context = {0, self, NULL, NULL, NULL}; 
CFReadStreamSetClient(
     stream, 
     kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 
     ASReadStreamCallBack, 
     &context); 

// schedule stream in current thread runloop, so that we DON'T block the mainthread 
CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); 

// create the callback function to handle reading from stream 
// NOTE: see where else in the code this function is named (ie CFReadStreamSetClient) 
static void ASReadStreamCallBack 
(
    CFReadStreamRef aStream, 
    CFStreamEventType eventType, 
    void* inClientInfo 
) 
{ 
    //handle events you registered above 
    // ie 
    if (eventType == kCFStreamEventHasBytesAvailable) { 
     // handle network data here.. 
     .. 
     // if something goes wrong, create an alert and run it through the main thread: 
     UIAlertView *alert = [ 
      [[UIAlertView alloc] 
       initWithTitle:title 
       message:message 
       delegate:self 
       cancelButtonTitle:NSLocalizedString(@"OK", @"") 
       otherButtonTitles: nil] 
      autorelease]; 
      [alert 
       performSelector:@selector(show) 
       onThread:[NSThread mainThread] 
       withObject:nil 
       waitUntilDone:NO];   
    }   
} 
+0

感謝您的幫助,但並不完全是我正在尋找的。我最終通過遵循下面的指導來解決這個問題。 http://benincosa.com/blog/?p=449無論如何謝謝你的負擔! – 2013-03-26 11:08:24