2016-07-23 59 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。