0

NSURLConnectionを使用してhttpをダウンロードしています。状態によっては、特定のダウンロード後に接続を切断しなければならない場合があります。たとえば、ダウンロードが30秒で完了した場合は、30秒後にダウンロードを停止する必要があります。また、これらのイベントをログに記録する必要があります。私の問題は、30秒後でもデータのダウンロードを続け、ダウンロードが完了した後にのみイベントがログに記録されることです。

簡単に言うと、ダウンロードを強制的に閉じ、http接続によって発生するすべてのデリゲートイベントを無効にします。複数の場所にフラグを設定したくないので、さらに複雑になります。何か案は?

更新:完全なシナリオ: NSURLReqeustオブジェクトでtimeoutIntervalを10秒に設定しました。これで、10秒間データが受信されなかった場合、10秒間が完全に正常に機能した後、接続が自動的に切断されます。しかし、ソフトウェアに別の機能があり、ダウンロードが指定された時間内に完了しない状態で接続を終了する必要があります。別のNSTimerを使用しています。NSTimerイベントが発生したときにフラグを設定するだけです。NSTimerを介してフラグが設定され、データの受信が停止した場合、次の10秒間起動される接続デリゲートがありません。今私の問題は、アボートイベントとタイムアウトイベントの両方が同時に発生することです。

4

2 に答える 2

2

さて、キャンセルイベントを送信することでNSURLConnectionを「キャンセル」できます。

[connection cancel];

Appleドキュメントを参照してください。

その前は、デリゲートをゼロにするだけで、デリゲートのコールバックに悩まされることはありません。

于 2012-11-29T10:48:40.013 に答える
1

オブジェクトを使用して、このメソッドNSURLRequestを使用してダウンロードしたevreyリクエストのタイムアウトを指定します。requestWithURL:cachePolicy:timeoutInterval:

NSURLConnectionのデリゲートが設定され、connection:didFailWithError:メソッドに応答するかどうかを確認してください。ANSURLConnectionは、このメソッドを呼び出すかconnectionDidFinishLoading:、接続の完了時に呼び出します。

'didFailWithError'メソッドを処理し、NSErrorオブジェクトを使用して失敗の理由を確認します。

ただし、サーバーから応答があり、応答時間が遅い場合は、を使用しNSTimerます。データをダウンロードするためのヘルパークラスを作成して、複数のインスタンスを作成し、NSTimerを設定して、クラスを複数のダウンロードに再利用できるようにします。ダウンロードが30秒以内に終了した場合は、タイマーを無効にします。それ以外の場合は、ダウンロードをキャンセルします[self.connection cancel]

次のコードを確認してください。

- (void)_startReceive
    // Starts a connection to download the current URL.
{
    BOOL                success;
    NSURL *             url;
    NSURLRequest *      request;

        // Open a connection for the URL.
        request = [NSURLRequest requestWithURL:url];
        assert(request != nil);

        self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
        assert(self.connection != nil);

        // If we've been told to use an early timeout for get complete response within 30 sec, 
        // set that up now.
            self.earlyTimeoutTimer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(_earlyTimeout:) userInfo:nil repeats:NO];
    }
}

- (void)_stopReceiveWithStatus:(NSString *)statusString
    // Shuts down the connection and displays the result (statusString == nil) 
    // or the error status (otherwise).
{
    if (self.earlyTimeoutTimer != nil) {
        [self.earlyTimeoutTimer invalidate];
        self.earlyTimeoutTimer = nil;
    }
    if (self.connection != nil) {
        [self.connection cancel];
        self.connection = nil;
    }
}

- (void)_earlyTimeout:(NSTimer *)timer
    // Called by a timer (if the download is not finish)
{
    [self _stopReceiveWithStatus:@"Early Timeout"];
}

- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response
    // A delegate method called by the NSURLConnection when the request/response 
    // exchange is complete.  
{ }

- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
    // A delegate method called by the NSURLConnection as data arrives.  We just 
    // write the data to the file.
{ }

- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
    // A delegate method called by the NSURLConnection if the connection fails. 
{
    NSLog(@"didFailWithError %@", error);   
    // stop Receive With Status Connection failed
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
    // A delegate method called by the NSURLConnection when the connection has been 
    // done successfully.  We shut down the connection with a nil status.
{
    NSLog(@"connectionDidFinishLoading");
    // If control reach here before timer invalidate then save the data and invalidate the timer
     if (self.earlyTimeoutTimer != nil) {
        [self.earlyTimeoutTimer invalidate];
        self.earlyTimeoutTimer = nil;
    }
}
于 2012-11-29T10:50:52.373 に答える