4

サーバーに到達できない場合(つまり)、現在メインスレッドをブロックしているため、現在、ネットワーク全体をバックグラウンドスレッドで実行しようとしています。

私は現在、次のコードを使用してネットワーク接続を作成しています。これを新しいバックグラウンドスレッドで実行する簡単な方法はありますか?

受信したメッセージをメインスレッドに戻すにはどうすればよいですか?バックグラウンドスレッドを介してメッセージを送信するにはどうすればよいですか?

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ipAdress, port, &readStream, &writeStream);
inputStream = (__bridge NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[inputStream open];
[outputStream open];
4

1 に答える 1

5

これはあなたが話していることを正確に行うチュートリアルです。オーディオストリーミングに重点を置いていますが、原則はまったく同じです(つまり、ワーカースレッドの生成、親スレッドとの通信など)。

考え方は単純です。新しいスレッドを作成してストリーミング作業を処理させてから、作成したスレッドに属する実行ループを使用してストリームリーダーをスケジュールします。ストリームには、特定のイベントが発生したときに発生するコールバックがあります(つまり、データの取得、接続のタイムアウトなど)。コールバックメソッドでは、メインスレッド(UIを処理するスレッド)にアラートを送信したり、通信したりできます。 。

これが正しい方向を示すためのコードですが、上記のチュートリアルからコードをダウンロードして実行すると、次のようになります。

// create a new thread
internalThread =
                [[NSThread alloc]
                    initWithTarget:self
                    selector:@selector(startInternal)
                    object:nil];
            [internalThread start];

// creating a stream inside the 'startInternal' thread*
stream = CFReadStreamCreateForHTTPRequest(NULL, message);

// open stream
CFReadStreamOpen(stream) 

// set callback functions
// ie say: if there are bites available in the stream, fire a callback etc
CFStreamClientContext context = {0, self, NULL, NULL, NULL};
CFReadStreamSetClient(
        stream,
        kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
        ASReadStreamCallBack,
        &context);

// schedule stream in current thread runloop, so that we DON'T block the mainthread
CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

// create the callback function to handle reading from stream
// NOTE: see where else in the code this function is named (ie CFReadStreamSetClient)
static void ASReadStreamCallBack
(
   CFReadStreamRef aStream,
   CFStreamEventType eventType,
   void* inClientInfo
)
{
    //handle events you registered above
    // ie
    if (eventType == kCFStreamEventHasBytesAvailable) {
        // handle network data here..
        ..
        // if something goes wrong, create an alert and run it through the main thread:
        UIAlertView *alert = [
            [[UIAlertView alloc]
                initWithTitle:title
                message:message
                delegate:self
                cancelButtonTitle:NSLocalizedString(@"OK", @"")
                otherButtonTitles: nil]
            autorelease];
            [alert
                performSelector:@selector(show)
                onThread:[NSThread mainThread]
                withObject:nil
                waitUntilDone:NO];        
    }          
}
于 2013-03-26T08:39:07.613 に答える