2012-05-13 71 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)。 –

相关问题