8

この質問がSOで何度も尋ねられたことは知っていますが、プロジェクトでうまく機能させることができませんでした...

だから、私はサブクラスNSOperation化し、それを使用してファイルをダウンロードさせたいNSURLConnection. それを行う正しい方法は何ですか?これが機能しない私のコードです: まず、すべての操作をループに追加しています:

DownloadFileOperation *operation;
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
for (int i=0; i<10; i++) {
operation = [[DownloadFileOperation alloc] init];
operation.urlString = pdfUrlString;
[queue addOperation:operation];
operation = nil; }

そして、ここに私のサブクラスがあります:

@interface DownloadHandbookOperation : NSOperation <NSURLConnectionDelegate>
{

}

@property (strong, nonatomic) NSString *urlString;

@end


@implementation DownloadHandbookOperation
{
    NSString *filePath;
    NSFileHandle *file;
    NSURLConnection * connection;
}

- (void)start
{
    if (![NSThread isMainThread])
    {
        [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
        return;
    }

    NSURL *url = [[NSURL alloc] initWithString:[self.urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req addValue:@"Basic ***=" forHTTPHeaderField:@"Authorization"];
    connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];

}

- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response
{
    NSString *filename = [[conn.originalRequest.URL absoluteString] lastPathComponent];
    filename = [filename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:filename];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];

    file = [NSFileHandle fileHandleForUpdatingAtPath:filePath] ;
    if (file)
    {
        [file seekToEndOfFile];
    }
    else
        [self finish];
}

- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
    if (file) {
        [file seekToEndOfFile];
    }
    [file writeData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
    [file closeFile];
    [self finish];
}

- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
    connection = nil;

    [self finish];
}

- (void)cancel
{
    [super cancel];
    [connection cancel];
}


- (void)finish
{
    NSLog(@"operationfinished.");
}


@end

私は何を間違っていますか?

4

1 に答える 1

8

「同時操作」として実行するには、操作を適切に構成する必要があります

同時実行プログラミング ガイド: 同時実行のための操作の構成

isConcurrent = YES他の状態フラグを返して適切に管理する必要がありisExecutingisFinishedKVO に準拠した方法で行う必要があります。


一般的な考え方を説明するために、Pulse のエンジニアからの投稿で、ダウンロードして確認できるわかりやすいデモ コードを使用してソリューションを説明しています。

Pulse Engineering ブログ: NSOperationQueues を使用した同時ダウンロード**

このコードは、NSURLConnection がアクティブな実行ループを持つスレッドで開始されるという要件も、メイン スレッドで確実に開始することによって処理します。

(** リンクは現在 archive.org になっています。pulse は買収されて古いサイトを削除したと思います)

于 2013-02-25T12:46:58.767 に答える