1

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

我实际上想要做的是取消调度(从主线程)并重新调度(到帮助程序/网络线程)我从第三方框架接收的打开的 NSInputStream 和 NSOutputStream(请参阅Can an open, but inactive, NSStream that是否将主线程上的调度移动到不同的线程?)。到目前为止,没有人回答这个问题,所以我正在尝试自己做这个,看看它是否可以工作。

为了测试什么是可能的,我正在尝试修改这里的代码(其中包括一个 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];
}

关于什么可能是错的任何想法?提前致谢!

4

1 回答 1

0

与以下问题中的代码类似的东西效果很好(我的应用程序中有类似的代码):

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

于 2012-11-05T20:34:31.753 回答