2

カスタムGCDキュー内のサーバーに接続しようとしています。これが私がやっている方法です。

- (void) initNetworkCommunication{
    if(!self.connQueue){
        self.connQueue = dispatch_queue_create("connection_queue", NULL);
    }

    dispatch_async(self.connQueue, ^(void) {
        if(self.inputStream ==nil && self.outputStream ==nil) {
            CFReadStreamRef readStream;
            CFWriteStreamRef writeStream;
            NSString *host= [[NSUserDefaults standardUserDefaults] objectForKey:@"ip_preference"];
            NSNumber *portNum = [[NSUserDefaults standardUserDefaults] objectForKey:@"port_preference"];

            int port = [portNum intValue];
            CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);

            CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
            CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);  

            self.inputStream = (__bridge NSInputStream *)readStream;
            self.outputStream = (__bridge NSOutputStream *)writeStream;
            [self.inputStream setDelegate:self];
            [self.outputStream setDelegate:self];

            [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
            [self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

            [self.outputStream open];
            [self.inputStream open];
        } else {
            NSLog(@"persistant connection alerady opened");
            return;
        }
    });
}

ここで、このコードをdispatch_syncに記述すると、デリゲート関数が正しく呼び出されます。

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

しかし、私がやりたいことであるdispatch_asynchを使用すると、デリゲート関数が呼び出されません。

私がこれまで読んだことから、GCDキューにはランループが関連付けられていますが、これらはシステムによって実行されないため、自分で実行する必要があります。私はこれを理論的には理解していますが、どのように行われていますか。どういうわけかこれに関連するソースをディスパッチしますか?

前もって感謝します。

4

2 に答える 2

7

このメソッドを後に追加します[self.inputStream open];

[[NSRunLoop currentRunLoop]run];

これにより、レシーバーは永続的なループに陥り、その間、接続されているすべての入力ソースからのデータを処理します。RunLoopsに関する Apple ドキュメントを参照してください

于 2012-12-24T13:42:08.307 に答える