2012-05-29 38 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

回答

相關問題