2011-11-09 77 views

回答

19

似乎沒有一種好的方法可以做到這一點。解決方案似乎是在您需要取消請求的情況下不使用新的[NSURLConnection sendAsynchronousRequest]

+0

這是不正確的;請參閱[我的帖子下面](http://stackoverflow.com/a/25784367/1255674)。 – Robert

3

我已經設法通過將sendAsynchronousRequest方法在一個單獨的DownloadWrapper類來做到這一點,方法如下:

// 
// DownloadWrapper.h 
// 
// Created by Ahmed Khalaf on 16/12/11. 
// Copyright (c) 2011 arkuana. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

@protocol DownloadWrapperDelegate 
- (void)receivedData:(NSData *)data; 
- (void)emptyReply; 
- (void)timedOut; 
- (void)downloadError:(NSError *)error; 
@end 

@interface DownloadWrapper : NSObject { 
    id<DownloadWrapperDelegate> delegate; 
} 
@property(nonatomic, retain) id<DownloadWrapperDelegate> delegate; 
- (void)downloadContentsOfURL:(NSString *)urlString; 
@end 

@implementation DownloadWrapper 
@synthesize delegate; 

- (void)downloadContentsOfURL:(NSString *)urlString 
{ 
    NSURL *url = [NSURL URLWithString:urlString]; 

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:TIMEOUT_INTERVAL]; 
    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 

    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
    { 
     if ([data length] > 0 && error == nil) 
      [delegate receivedData:data]; 
     else if ([data length] == 0 && error == nil) 
      [delegate emptyReply]; 
     else if (error != nil && error.code == ERROR_CODE_TIMEOUT) 
      [delegate timedOut]; 
     else if (error != nil) 
      [delegate downloadError:error]; 
    }]; 
} 
@end 

爲了利用這個類,我這樣做時,在除了聲明DownloadWrapper *downloadWrapper變量(在接口聲明)和執行該處理的響應或缺乏一個的協議方法:

NSString *urlString = @"http://yoursite.com/page/to/download.html"; 
downloadWrapper = [DownloadWrapper alloc]; 
downloadWrapper.delegate = self; 
[downloadWrapper downloadContentsOfURL:urlString]; 

然後,我只是執行以下操作來「取消」的連接時的視圖即將二消失:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    downloadWrapper = nil; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [downloadWrapper setDelegate:nil]; 
} 

就這麼簡單。這將有希望模仿記載cancel方法,其中指出,它執行以下操作:

一旦這個方法被調用時,接收器的代表將不再 收到任何消息此NSURLConnection的。

我擔心這個(有點幼稚)方法是指數據包仍然會響應我們的URL請求來通過 - 只是我們不再「在聽」爲代表。但後來我意識到,一旦URL請求被髮送完畢,就沒有辦法阻止回覆給我們的響應 - 我們只能忽視它(如果不是在這個級別,那麼仍然在網絡層次中的較低級別) 。如果我錯了,請糾正我。

無論哪種方式,希望這有助於。

+0

我在這個解決方案中遇到的一個問題是,您一次只能有一個委託。 sendAsynchronousRequest的一個好處是:queue:completionHandler:可以用來自不同對象的大量請求來轟擊它。如果你包裝委託生命,但原始請求對象不會......崩潰。當我嘗試在全球APIClient中使用這種方法時,這是一個問題。 所以我同意Micah,但這對於一個簡單的實現來說是一個可行的解決方案。 – GnarlyDog

+2

你是對的,這太簡單了 - 即使是我所需要的。我改變了我的方法,並利用Nick Lockwood的[RequestQueue](https://github.com/nicklockwood/RequestQueue)類。它有方法來取消所有(併發)請求或特定的請求,如果需要的話。 – pxlshpr

相關問題