0

我正在使用 NSURLConnection 进行 http 下载。根据具体情况,我可能不得不在特定下载后断开连接。比如说,如果我的下载在 30 秒内完成,那么其他明智的下载应该在 30 秒后停止。我还必须记录这些事件。我的问题是,即使在 30 秒后,它也会继续下载数据,并且只有在下载完成后才会记录事件。

简而言之,我想强制关闭下载,还想禁用所有由 http 连接触发的委托事件。我不想在多个位置设置标志,这会使事情进一步复杂化。有任何想法吗?

更新:完整场景: 我在 NSURLReqeust 对象中将 timeoutInterval 设置为 10 秒。现在,如果 10 秒内没有收到数据会发生什么情况,连接会在 10 秒后自动断开,工作正常。但是我的软件中有另一个功能需要在给定时间内未完成下载的情况下终止连接。我正在使用单独的 NSTimer。我所能做的就是在触发 NSTimer 事件时设置一个标志。现在,如果通过 NSTimer 设置了标志并且数据停止进入,我没有将在接下来的 10 秒内触发的连接委托。现在我的问题是中止事件和超时事件同时发生。

4

2 回答 2

2

好吧,你“可以”通过发送一个取消事件来取消一个 NSURLConnection:

[connection cancel];

请参阅 Apple文档

在此之前,只需 nil 代表,您不应该受到任何代表回调的骚扰。

于 2012-11-29T10:48:40.013 回答
1

使用object 为您使用此方法NSURLRequest下载的 evrey 请求指定超时。requestWithURL:cachePolicy:timeoutInterval:

请检查您NSURLConnection的委托是否已设置并响应该connection:didFailWithError:方法。ANSURLConnection调用此方法或connectionDidFinishLoading:在连接完成时调用。

处理'didFailWithError'方法并使用NSError对象检查失败的原因。

但是,如果您从服务器获得响应并且响应时间很慢,则使用NSTimer. 创建用于下载数据的 Helper 类,以便您可以通过创建多个实例并在其中设置 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 回答