如何等待ftp请求完成,然后继续程序

时间:2012-05-13 05:03:57

标签: iphone objective-c multithreading

我使用“SimpleFTPSample”来执行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,如果请求在我定义的TIMEOUTFTP中正确完成,networkStream也将被关闭。我在另一个地方使用这个方法:

- (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]);
    }

}

情况是该程序停留在“while(ftpService.isReceiving){}”。我不熟悉Multiple Thread。可能是我无法正确理解运行循环。有人能告诉我为什么会这样,以及如何实现我的目的?

1 个答案:

答案 0 :(得分:2)

在让程序继续进行之前,您应该重新考虑是否真的要等待收到的数据。相反,您应该将UI置于一种状态,即显示它正在下载并限制用户可以执行的操作,将控制权返回给应用程序的主事件循环,并让它在收到数据时调用您的委托方法。只有收到数据后,才能解锁用户界面并继续执行下一步,无论是什么。

阻止应用程序的主线程会导致糟糕的用户体验,并可能导致您的应用终止。

但是,如果你真的想这样做,你需要运行运行循环而不是忙碌的等待。类似的东西:

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

实际上,在你自己运行运行循环的情况下,你应该在这里和你安排流的地方使用不同的运行循环模式。默认的运行循环模式将包含来自其余框架的运行循环源,并且让那些从您自己的内部运行循环触发它们是危险的。只需使用一个任意字符串,该字符串可能对于该模式的程序是唯一的。

运行循环是各种事件和输入源(以及计时器)的集合。您的代码和框架的各个部分都将在运行循环中调度源。它们依赖于正在运行的运行循环,以便接收事件/输入/定时器触发并处理它们。通过不运行运行循环而只是忙于等待,您阻止了流从FTP连接接收数据并进行处理。