2016-12-10 5 views
0

私はtableViewと40の細胞を持っています。ユーザーがセルをクリックすると、セルがチェックされます(ファイルが存在するかどうか)。ファイルが存在しない場合、ダウンロードが開始されます。Objective-C:40ファイルをダウンロード

質問:

ユーザーが、私はこのコードを使用している場合私のアプリが失敗したり、遅れる一度にすべての40個のファイルをダウンロードしたい場合は?あなたが問題を引き起こして40の同時ダウンロードに問題があってはなりません

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

if (indexPath.row == 1) { 
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsDirectory = [paths objectAtIndex:0]; 
        NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"1.mp3"]; 
        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:false]; 
        if (!fileExists) { 

         UIAlertController * alert = [UIAlertController 
                 alertControllerWithTitle:@"1" 
                 message:@"1" 
                 preferredStyle:UIAlertControllerStyleActionSheet]; 
         UIAlertAction* actionAdd = [UIAlertAction 
                actionWithTitle:@"OK" 
                style:UIAlertActionStyleDefault 
                handler:^(UIAlertAction * action) 
                { 
                 [alert dismissViewControllerAnimated:YES completion:nil]; 

                 _url1 =[NSURL URLWithString:@"link"]; 
                 _downloadTask1 = [_session downloadTaskWithURL:_url1]; 
                 [_downloadTask1 resume]; 

                 self.circularPV1 = [[FFCircularProgressView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)]; 

                 [tableView cellForRowAtIndexPath:indexPath].accessoryView = self.circularPV1; 
                 [self.view addSubview:_circularPV1]; 

                 [_circularPV1 startSpinProgressBackgroundLayer]; 

                }]; 

         UIAlertAction* actionCancel = [UIAlertAction 
                 actionWithTitle:@"Cancel" 
                 style:UIAlertActionStyleCancel 
                 handler:^(UIAlertAction * action) 
                 { 
                  [alert dismissViewControllerAnimated:YES completion:nil]; 
                 }]; 
         [alert addAction:actionAdd]; 
         [alert addAction :actionCancel]; 
         alert.popoverPresentationController.sourceView = self.view; 
         alert.popoverPresentationController.sourceRect = CGRectMake(self.view.bounds.size.width/3.4, self.view.bounds.size.height/4.0, 1.0, 1.0); 
         [self presentViewController:alert animated:YES completion:nil]; 
        } 
        if (fileExists) { 
         [self performSegueWithIdentifier: @"Segue" sender: self]; 
        } 
       } 
} 
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location 
{ 

    if (downloadTask == _downloadTask1) { 

     _paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     _documentsDirectory1 = [_paths1 objectAtIndex:0]; 
     NSFileManager *fileManager = [NSFileManager defaultManager]; 
     NSURL *newLocation = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@/1.mp3", _documentsDirectory1]]; 
     NSError *error; 
     [fileManager copyItemAtURL:location toURL:newLocation error:&error]; 
    } 
} 

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite; 
{ 
    if(downloadTask == _downloadTask1){ 

     self.p1 = (float) totalBytesWritten; 
     self.p2 = (float) totalBytesExpectedToWrite; 

     [_circularPV1 setProgress:(p2/p2)]; 
     [_circularPV1 stopSpinProgressBackgroundLayer]; 


    } 
+0

ファイルを読み書きするために別のスレッドを使用してください。 –

+0

私は 'dispatch_async(dispatch_get_main_queue()、^ { });'を追加する必要があります。 – user

+0

ファイルをダウンロードするには、独自の(バックグラウンド)操作キューと 'NS(ブロック)操作 'を使用します。例えば、[this Apple sample code](https://developer.apple.com/library/content/samplecode/LazyTableImages/Introduction/Intro.html)を見てください。 – vadian

答えて

0

:1ファイルをダウンロードするための

コード。 NSURLSessionは、複数のダウンロードを管理するように設計されています。それは実際には一度にいくつかダウンロードし、残りは待つでしょう。

ダウンロードを行うためにバックグラウンド操作を使用するVadianの推奨は無意味です。あなたのコードはすでにNSURLSessionを使用しています。これはバックグラウンドでダウンロードを行う独自のキューを管理しています。彼のコメントは無視してください。彼は間違っている。

NSURLSessionもバックグラウンドからデリゲートメソッドを呼び出すので、ファイルを移動するためのコードもバックグラウンドから実行されています。

問題は、didWriteDataメソッドがUIを更新していることです。上記のように、NSURLSessionはバックグラウンドからデリゲートメソッドを呼び出すため、これらのUI呼び出しはバックグラウンドスレッドで実行されていますが、これは許可されていません。メインスレッドへの呼び出しで、NSURLSessionデリゲートメソッドから行ったすべてのUIKit呼び出しをラップする必要があります。このように、例えば:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 
    didWriteData:(int64_t)bytesWritten 
    totalBytesWritten:(int64_t)totalBytesWritten 
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite; 
{ 
    if(downloadTask == _downloadTask1){ 

     self.p1 = (float) totalBytesWritten; 
     self.p2 = (float) totalBytesExpectedToWrite; 
     //Make the UI calls below on the main thread. 
     dispatch_async(dispatch_get_main_queue) { 
      [_circularPV1 setProgress:(p2/p2)]; 
      [_circularPV1 stopSpinProgressBackgroundLayer]; 
     } 
    } 
} 

意味がありません任意の方法、の声明場合

if (indexPath.row == 1) { 

が浮いている外で始まるコード。そのコードはどこに住んでいますか?

+0

'if(indexPath.row == 1){' '(void)tableview:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath'問題のコードを追加します – user

-1
- (void)startDownloadwithURL:(NSURL*)url{ 


    if (_isUsed) { 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self startDownloadwithURL:url]; 
     return; 

    }); 
    } 
    _downloadTask1 = [_session downloadTaskWithURL:url]; 
    [_downloadTask1 resume]; 

} 
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location 
{ 

if (downloadTask == _downloadTask1) { 
    _isUsed = NO; 

    _paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    _documentsDirectory1 = [_paths1 objectAtIndex:0]; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSURL *newLocation = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@/1.mp3", _documentsDirectory1]]; 
    NSError *error; 
    [fileManager copyItemAtURL:location toURL:newLocation error:&error]; 
} 
} 

このコードをダウンロードしてください。 startDownloadwithURL:ダウンロードを開始するURL(NSURL *)

+0

そのような新しいダウンロードを遅らせることに意味はありません。 NSURLSessionは多数のダウンロードを管理するように設定されています。一度にいくつかのダウンロードを実行するだけです(私は3と言いたい)残りは待つでしょう。 –

+0

答えが間違っていれば、この解決法は間違いではないが、この解決法も間違っていないと答えはない。 – vp2698

+0

あなたの答えは誤解を招くような情報を提供し、不必要に複雑で無益な何かを行うという初心者に示唆する。それは活動的な害を及ぼすことはありませんが、有用なことは何もしません。 –

関連する問題