2013-02-25 2 views
8

内非同期NSURLConnectionがSOに何度も聞かれたが、私はそれは私のプロジェクトで動作させることが出来なかった私はNSOperationをサブクラス化し、それを作りたいですNSURLConnectionを使用してファイルをダウンロードしてください。それを行う正しい方法は何ですか? まず、私は、ループ内のすべての私の操作を追加している:ここ は動作しません、私のコードがあるiOSのは - そう</p> <p>...私はこの質問を知ってNSOperation

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 

私が間違って何をやっています?

+0

私は 'NSURLConnection'はメインスレッドから呼び出される必要があり、それがそうしないと思います背景スレッドから呼び出された場合は何か...また、メインスレッドから呼び出されても、バックグラウンドでネットワークの処理を行います。次に、メインスレッドからデリゲート関数を呼び出します。 – jjv360

+0

NSOperationをメインスレッドで実行させますか? – Oleg

+0

'[NSOperationQueue mainQueue] addOperation:operation]' ... – jjv360

答えて

8

あなたは適切にあなたがisConcurrent = YESを返し、適切に他の状態フラグを管理し、KVO準拠した方法でisExecutingisFinishedする必要があり、「同時操作」

Concurrency Programming Guide: Configuring Operations for Concurrent Execution

として実行するように動作を設定する必要があります。ここでの一般的な考え方を説明するために


は、あなたがダウンロードして確認することができますいくつか従うことは簡単デモコードとその解決策を説明し、パルスのエンジニアからの投稿です。

Pulse Engineering Blog: Concurrent Downloads using NSOperationQueuesは**

また、このコードはNSURLConnectionはそれがメインスレッド上でそれを起動することを確実にすることにより、アクティブな実行ループでスレッド上で開始された要求を処理します。

(**リンクはarchive.orgに今、私はパルスが取得され、ダウン、古いサイトをとっていると思います)

+0

リンクありがとうございました! – Oleg

+0

回答ありがとう:-) – Arkan

+0

リンクが壊れています。 :( – Suz

関連する問題