2012-05-29 37 views
1

有谁知道一个简单的例子,在单独的线程上创建(基于网络的)NSStream?单独线程上基于网络的NSStream的良好示例?

我实际上试图做的是从第三方框架(参见Can an open, but inactive, NSStream that is scheduled on the main thread be moved to a different thread?)中取消调度(从主线程)并重新安排(到助手/网络线程)一个打开的NSInputStream和NSOutputStream。到目前为止,还没有人回答这个问题,所以我正在努力自己做这件事,看看它是否能够发挥作用。

要测试什么是可能的,我想在这里修改的代码(包括iOS的客户端,并在很短的,基于Python服务器[真棒!): http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server

从而使NSInputStream后和NSOutputStream创建并打开我试图将其移动到辅助线程上。

我遇到的挑战是帮助程序线程似乎没有响应委托来自数据流的消息或我通过发送的任何消息: performSelector:onThread:withObject:waitUntilDone:modes :.我怀疑我在设置助手线程的NSRunLoop时遇到了问题(请参阅下面的networkThreadMain)。

因此,[ChatClientViewController viewDidLoad中现在的样子:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [self initNetworkCommunication]; 
    [self decoupleStreamsFromMainThread]; 
    [self spoolUpNetworkThread]; 

    inputNameField.text = @"cesare"; 
    messages = [[NSMutableArray alloc] init]; 

    self.tView.delegate = self; 
    self.tView.dataSource = self; 

} 

随着这些实现:在什么可能是错误

- (void) initNetworkCommunication { 

    CFReadStreamRef readStream; 
    CFWriteStreamRef writeStream; 
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"localhost", 80, &readStream, &writeStream); 

    inputStream = (NSInputStream *)readStream; 
    outputStream = (NSOutputStream *)writeStream; 
    [inputStream setDelegate:self]; 
    [outputStream setDelegate:self]; 
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [inputStream open]; 
    [outputStream open];  
} 

- (void) decoupleStreamsFromMainThread 
{ 
    inputStream.delegate = nil; 
    outputStream.delegate = nil; 

    [inputStream removeFromRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode]; 
    [outputStream removeFromRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode]; 
} 

- (void) spoolUpNetworkThread 
{ 
    [NSThread detachNewThreadSelector: @selector(networkThreadMain) toTarget: self withObject: nil]; 
} 

- (void) networkThreadMain 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool 

    static dispatch_once_t once; 
    dispatch_once(&once, ^{ 
     [self rescheduleThreads]; 
     ((ChatClientAppDelegate *)[[UIApplication sharedApplication] delegate]).networkThread = [NSThread currentThread]; 

     [inputStream setDelegate:self]; 
     [outputStream setDelegate:self]; 

     NSLog(@"inputStream status is: %@", [NSInputStream streamStatusCodeDescription: [inputStream streamStatus]]); 
     NSLog(@"outputStream status is: %@", [NSOutputStream streamStatusCodeDescription: [outputStream streamStatus]]); 

     [[NSRunLoop currentRunLoop] runUntilDate: [NSDate distantFuture]]; 
    }); 

    [pool release]; // Release the objects in the pool. 
} 

- (void) rescheduleThreads 
{ 
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
} 

任何想法?提前致谢!

+0

我可以提供的项目对那些希望看到它在整体。 – xyzzycoder

回答

相关问题