2012-05-13 73 views
0

我使用「SimpleFTPSample」來執行ftp請求以列出有關信息。該部分代碼如下:如何等待ftp請求完成,然後繼續執行程序

- (void)_startReceive 
{ 
...... 
    self.networkStream = (NSInputStream *) ftpStream; 
    self.networkStream.delegate = self; 
    [self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

    [NSTimer scheduledTimerWithTimeInterval:TIMEOUTFTP target:self 
            selector:@selector(dealTimeOut:) userInfo:nil repeats:NO]; 
...... 
} 

我還設置了的NSTimer TIMEOUTFTP後停止的NetworkStream中,也的NetworkStream將被關閉,如果該請求被內TIMEOUTFTP我定義正確完成。我使用的方法在另一個地方是這樣的:

- (void)downLoadData 
{ 
    NSArray* receivedData; 
    [ftpService _startReceive]; 

    //wait until the network is closed 
    while (ftpService.isReceiving) {} 

    receivedData = ftpService.dataArray; 

    if([receivedData count] == 0) { 
     NSLog(@"no data get"); 
    } 
    else { 
     NSLog(@"get data number %d", [receivedData count]); 
    } 

}

的情況是,該計劃停留在 「一段時間(ftpService.isReceiving){}」。我不熟悉Multiple Thread。可能是我不正確地理解運行循環。有人能告訴我爲什麼會發生這種情況,以及如何達到我的目的?

回答

2

在讓程序繼續之前,您應該重新考慮您是否真的想等待收到的數據。相反,你應該把你的用戶界面置於一個狀態,它顯示它正在下載並限制用戶可以做的事情,將控制權交還給應用程序的主事件循環,並且在接收到數據時讓它調用你的委託方法。只有收到數據後,才能解鎖UI並繼續下一步,無論如何。

阻止應用程序的主線程將導致糟糕的用戶體驗,並可能會終止您的應用程序。

但是,如果您真的想這樣做,您需要運行運行循環而不是忙於等待。喜歡的東西:

while (ftpService.isReceiving) 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 

其實,在你自己運行的運行循環這種情況下,你都應該在這裏使用一個不同的運行循環模式,並在那裏你安排流。默認運行循環模式將包含來自其他框架的運行循環源,並且讓那些從您自己的內部運行循環中啓動的模塊是危險的。只需使用一個任意字符串,這對您的程序來說可能是獨一無二的。

運行循環是事件和輸入(和定時器)的各種來源的集合。代碼和框架的各個部分都將在運行循環中安排源代碼。它們依賴於正在運行的運行循環以接收事件/輸入/定時器觸發並處理它們。通過不運行運行循環並只是忙於等待,您就阻止了流接收來自FTP連接的數據並處理它。

+0

謝謝!你的代碼做的話。但我不明白你想告訴我什麼。我想我應該更多地瞭解運行循環。 – itenyh

+0

實際上,這是在第二個線程從服務器加載數據。這樣做會導致可怕的結果嗎? – itenyh

+0

在後臺線程上,可以阻止等待數據。你可以使用我展示的代碼。 (通常不需要使用單獨的線程,因爲API支持異步使用,但是沒問題。)如果您想了解有關運行循環的更多信息,請參閱[Apple的文檔](https://developer.apple.com/library /ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html)。 –

相關問題