2013-03-26 61 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