2012-05-29 5 views
1

누구나 별도의 스레드에 (네트워크 기반) NSStream을 만드는 간단한 예제를 알고 있습니까?별도의 스레드에서 네트워크 기반 NSStream의 좋은 예는 무엇입니까?

실제로 수행하려고하는 것은 제 3 자 프레임 워크 (Can an open, but inactive, NSStream that is scheduled on the main thread be moved to a different thread? 참조)에서받은 열려있는 NSInputStream 및 NSOutputStream을 기본 스레드에서 스케줄을 해제하고 (도우미/네트워크 스레드에) 다시 스케줄하는 것입니다. 지금까지 아무도이 질문에 답하지 못했기 때문에이 일을 직접 할 수 있는지 알아보기 위해 노력하고 있습니다. 무엇이 가능한지 테스트하려면

, 나는 여기에 코드를 수정하는 것을 시도하고있다 (A 아이폰 OS 클라이언트와 매우 짧은, 파이썬 기반 서버 포함 [최고를!]) : 그래서 http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server

그 NSInputStream 후 NSOutputStream이 생성되고 열리 며 헬퍼 스레드로 이동하려고 시도합니다.

내가 겪고있는 문제는 도우미 스레드가 스트림 또는 지연되는 메시지의 메시지를 위임하는 데 응답하지 않는 것 같습니다. performSelector : onThread : withObject : waitUntilDone : modes :. 헬퍼 스레드의 NSRunLoop 설정에 문제가 있다고 생각합니다 (아래 networkThreadMain 참조). 이러한 구현과

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

어떤 아이디어가 잘못 될 일에

그래서, [ChatClientViewController가있는 viewDidLoad] 지금처럼 보인다? 미리 감사드립니다! 아래의 질문에 코드의 라인을 따라

+0

내가 전체를보고 싶으면 그에게 프로젝트를 제공 할 수 있습니다 . – xyzzycoder

답변