在单独的线程上基于网络的 NSStreams 的良好示例



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

我实际上要做的是取消调度(从主线程)并重新调度(到帮助程序/网络线程)我从第三方框架接收的打开的 NSInputStream 和 NSOutputStream(请参阅可以在主线程上调度的开放但非活动的 NSStream 移动到不同的线程吗?)。到目前为止,还没有人回答这个问题,所以我正在尝试自己做这件事,看看它是否可以发挥作用。

为了测试可能的情况,我正在尝试修改此处的代码(其中包括一个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];
}

关于可能出现什么问题的任何想法?提前感谢!

下面问题中的代码行的内容运行良好(我的应用程序中有类似的代码):

如何在另一个线程上正确打开和关闭 NSStream

最新更新