別のスレッドで(ネットワークベースの)NSStreamを作成する簡単な例を知っている人はいますか?
私が実際にやろうとしているのは、サードパーティのフレームワークから受け取っているオープンなNSInputStreamとNSOutputStreamを(メインスレッドから)スケジュール解除し、(ヘルパー/ネットワークスレッドに)再スケジュールすることです(オープンであるが非アクティブなNSStreamを参照してください。メインスレッドでスケジュールされているのは別のスレッドに移動されますか?)。これまで誰もその質問に答えていないので、私はそれが機能するかどうかを確認するために自分でこれをやろうとしています。
何が可能かをテストするために、ここでコードを変更しようとしています(iOSクライアントと非常に短いPythonベースのサーバー[素晴らしい!]を含む): http ://www.raywenderlich.com/3932/how-to -ソケットベースのiphone-app-and-serverを作成します
NSInputStreamとNSOutputStreamが作成されて開かれた後、それをヘルパースレッドに移動しようとします。
私が経験している課題は、ヘルパースレッドが、ストリームからの委任メッセージや、performSelector:onThread:withObject:waitUntilDone:modes:を介して送信しているメッセージに応答していないように見えることです。ヘルパースレッドのNSRunLoopの設定で何か問題が発生していると思われます(以下のnetworkThreadMainを参照)。
したがって、[ChatClientViewControllerviewDidLoad]は次のようになります。
- (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];
}
何が間違っているのかについてのアイデアはありますか?前もって感謝します!