Мне удалось сделать это, поместив метод 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-запрос был отправлен, на самом деле нет никакого способа остановить возвращение ответа нам - мы можем только игнорировать его (если не на этом уровне, то все еще на каком-то более низком уровне в сетевой иерархии),Пожалуйста, поправьте меня, если я ошибаюсь.
В любом случае, надеюсь, это поможет.