2012-12-24 36 views
2

我試圖連接到自定義GCD隊列中的服務器。這是我如何做的。如何在GCD的runloop中安排事件

- (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,但這些不是由系統運行的,我們需要自己做。我理論上理解這一點,但是它是如何完成的。派遣與此有關的資源?

謝謝您提前。

回答

7

[self.inputStream open];

[[NSRunLoop currentRunLoop]run]; 

這使接收機成永久循環,在此期間其從所有連接的輸入源處理數據添加此方法。 約RunLoops

+0

凡在上面的代碼中我稱這個方法?剛剛[self.inputStream打開]後?我是否會爲我計劃的兩個活動調用兩次? – ameyazing

+0

非常感謝@安德魯。這工作像一個魅力。 – ameyazing

+0

@ameyazing:不客氣 – Andrew

1

另一種方式看到蘋果文檔讓上dispatch_get_main_queue運行時使用dispatch_async();