2016-07-23 66 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]; 

一切正常

回答

0

應該把一切main threadmain thread中唯一保留的是UI updates

事實上,在main thread中所做的每個動作都會阻塞接口,直到動作結束。你想要的是你的下載在background執行,並有只有你的UI updatesmain thread

你必須做的是下面這段代碼:

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

對於您的情況下,代碼應該是這樣的:

- (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 */ }); 

內將在主線程上執行。在大多數情況下,您應該避免執行那裏的長進程,因爲在您的任務完成之前,ui(您的按鈕)無法響應。

所以儘量使用像這樣的背景下載

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

,並使用您的解決方案後,下載完成了更新的主線程UI。