2016-07-23 6 views
0

このファイルをマイデバイスにダウンロードするには、次のようにします。しかし、99%の読み込みインターフェイスの停止(私はボタンをクリックすることはできません)。 20秒後にすべて正常に動作し、ロード= 100%。インターフェイスが99%の負荷で停止するのはなぜですか?それを修正するには?デバイス上のファイルをダウンロードしようとすると、インターフェイスがブロックされています。

- (void)viewDidLoad 
{ 
dispatch_async(dispatch_get_main_queue(), ^{ 

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

    [self.progressView setProgress:0 animated:NO]; 
} 

- (IBAction)btnClicked:(id)sender { 
    if(_downloadTask == nil){ 

     _url =[NSURL URLWithString:@"https://www.nsw.gov.au/sites/default/files/bg-view-nsw-media.png"]; 

     _downloadTask = [_session downloadTaskWithURL:_url1]; 

     [_downloadTask resume]; 

    } 

    else 

    [_downloadTask resume]; 
} 

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"image1.mp3"]; 
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO]; 


    NSData *urlData = [NSData dataWithContentsOfURL:_url]; 
    [urlData writeToFile:filePath atomically:YES]; 
} 

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite; 
{ 
dispatch_async(dispatch_get_main_queue(), ^{ 
    [ _progressView setProgress:totalBytesWritten/totalBytesExpectedToWrite animated:YES]; 

    NSString *percentage = [NSString stringWithFormat:@"%d%%", (int)((totalBytesWritten/totalBytesExpectedToWrite)*100)]; 
    [_label setText:[NSString stringWithFormat:@"%@%%", percentage]]; 

    NSLog(@"%lld", totalBytesWritten); 

    _label = [[UILabel alloc]initWithFrame:CGRectMake(91, 15, 500, 50)]; 
    [_label setText: percentage]; 
    _label.numberOfLines = 1; 
    _label.backgroundColor = [UIColor blackColor]; 
    _label.textColor = [UIColor whiteColor]; 
    _label.textAlignment = NSTextAlignmentCenter; 
    [self.view addSubview:_label]; 


    }); 

UPD

その後、私はこのコードを削除

NSData *urlData = [NSData dataWithContentsOfURL:_url]; 
    [urlData writeToFile:filePath atomically:YES]; 

すべてはあなたmain threadすべてを置くべきではありません罰金

答えて

0

に動作します。 main threadに保管する唯一のものはUI updatesです。

実際、アクションが完了するまで、main threadで行われたすべてのアクションは、インターフェイスをブロックします。あなたが望むのは、ダウンロードをbackgroundで行い、のみUI updatesmain threadにすることです。あなたがしなければならないことは、このコードを以下れる

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"image1.mp3"]; 
     BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO]; 


     NSData *urlData = [NSData dataWithContentsOfURL:_url]; 
     [urlData writeToFile:filePath atomically:YES]; 
    }); 
} 
+0

は機能しません。コード内でどのように見えますか? – user214155

+0

私はこの行[urlData writeToFile:filePath atomically:YES]と思います。 (そしておそらく上記のもの)はバックグラウンドでコールする必要があります。 – AnthoPak

+0

私の質問が更新されます。ご確認ください – user214155

0

あなた

dispatch_async(dispatch_get_main_queue(), ^{ /* code */ }); 

意志の内部コードを:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    //Do background work 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     //Update UI 
    }); 
}); 

あなたのケースのためにコードは次のようになりますメインスレッド上で実行されます。ほとんどの場合、ui(あなたのボタン)はタスクが完了するまで応答できないので、そこでは長いプロセスの実行を避けるべきです。

だから、バックグラウンドダウンロード

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ /* background download*/ }); 

のために、このようなものを使用し、ダウンロードがメインスレッド上のUIを更新するために完了した後、あなたのソリューションを使用するようにしてください。

関連する問題