在我的设备上使用此代码下载文件。但是在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 :(得分:0)
你不应将{em>所有内容放在main thread
中。 main thread
中唯一要保留的内容是UI updates
。
实际上,main thread
中的每个操作都会阻止界面,直到操作完成。您想要的是在background
中执行下载,并在UI updates
中仅 main 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];
});
}
答案 1 :(得分:0)
中的代码
import React from 'react';
import ReactDOM from 'react-dom';
import Router from 'react-router';
import { DefaultRoute, Link, Route, RouteHandler } from 'react-router';
import LoginHandler from './components/Login.js';
let App = React.createClass({
render() {
return (
<div className="nav">
<Link to="app">Home</Link>
<Link to="login">Login</Link>
{/* this is the importTant part */}
<RouteHandler/>
</div>
);
}
});
let routes = (
<Route name="app" path="/" handler={App}>
<Route name="login" path="/login" handler={LoginHandler}/>
</Route>
);
Router.run(routes, function (Handler) {
ReactDOM.render(<Handler/>, document.body);
});
将在主线程上执行。在大多数情况下,您应该避免在那里执行长进程,因为在您的任务完成之前,ui(您的按钮)无法响应。
所以尝试使用类似的东西进行后台下载
dispatch_async(dispatch_get_main_queue(), ^{ /* code */ });
并在下载完成后使用您的解决方案在主线程上更新您的ui。