2012-05-13 4 views
0

"SimpleFTPSample"を使用して、デリート情報のリストをftpリクエストします。コードの一部は以下の通りである:私もTIMEOUTFTP後networkStreamを停止するようにNSTimerを設定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]; 
...... 
} 

要求は、私が定義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]); 
    } 

}

状況は、プログラムが "(ftpService.isReceiving){}、一方" で立ち往生することです。私は複数のスレッドに精通していません。私は実行ループを正しく理解していないかもしれません。誰かがなぜこれが起こり、私の目的を達成する方法を教えてもらえますか?

答えて

2

実際に受信したデータを待ってからプログラムを進めるかどうか再考する必要があります。その代わりに、ダウンロードしていることを示す状態にUIを配置し、ユーザーの操作を制限し、アプリケーションのメインイベントループに制御を戻し、データが受信されたときに委譲メソッドを呼び出させる必要があります。データが受信されると、UIのロックを解除して次のステップに進む必要があります。

アプリのメインスレッドをブロックすると、ユーザーエクスペリエンスが低下し、アプリが終了することがあります。

これを本当にやりたいのであれば、ビジーな待ち時間ではなく実行ループを実行する必要があります。ような何か:

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

実際には、あなたが実行ループを自分で実行しているこのケースでは、両方のこことどこでストリームをスケジュールする別の実行ループモードを使用する必要があります。デフォルトの実行ループモードには、残りのフレームワークからの実行ループソースが含まれます。これらの実行ループは、自分の内部ループから起動するのは危険です。モードのためにあなたのプログラムに一意である可能性のある任意の文字列を使用してください。

実行ループは、イベントと入力(およびタイマー)のさまざまなソースの集合です。コードとフレームワークのさまざまな部分の両方が、実行ループでソースをスケジュールします。それらは、イベント/入力/タイマー・ファイアを受信して​​処理するために実行される実行ループに依存します。実行ループを実行しておらず、ビジー待機中であることによって、ストリームがFTP接続からデータを受信して​​処理するのを妨げていました。

+0

ありがとうございます!あなたのコードは単語です。しかし、私はあなたが私に言いたいことを理解できません。私は、実行ループについてもっと知るべきだと思います。 – itenyh

+0

実際には、これはサーバーからデータをロードするための2番目のスレッドにあります。このようなことがひどい結果につながるでしょうか? – itenyh

+0

バックグラウンドスレッドでは、データの待機をブロックすることはできます。あなたは私が示したコードを使用することができます。 (APIは非同期の使用をサポートしているので、通常は別のスレッドを使用する必要はありませんが、問題ありません)。実行ループについて詳しく知りたい場合は、[Appleのドキュメント](https://developer.apple.com/library) /ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html)。 –

関連する問題