如何在GCD中的runloop中安排事件

时间:2012-12-24 13:30:14

标签: ios grand-central-dispatch

我正在尝试连接到自定义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队列有一个与它们相关的runloop,但这些不是由系统运行的,我们自己需要这样做。我在理论上理解这一点,但是它是如何完成的。以某种方式调度与此相关的来源?

提前谢谢你。

2 个答案:

答案 0 :(得分:7)

[self.inputStream open];

之后添加此方法
[[NSRunLoop currentRunLoop]run];

这会使接收器进入永久循环,在此期间它会处理来自所有连接输入源的数据。 请参阅有关RunLoops

的Apple文档

答案 1 :(得分:1)

另一种方法是在使用dispatch_get_main_queue

时在dispatch_async();上运行