Ios 在循环中设置进度视图,或更新进度视图 for(int i=0;i
简单的解决方案是异步执行此操作,在执行时更新进度视图:Ios 在循环中设置进度视图,或更新进度视图 for(int i=0;i,ios,iphone,uiprogressview,Ios,Iphone,Uiprogressview,简单的解决方案是异步执行此操作,在执行时更新进度视图: 创建进度视图并将其添加到视图中 将代码分派到后台队列 每次下载完成后,将进度视图的更新发送回主队列 在伪代码中,这看起来像 for (int i=0; i<[array count]; i++) { NSError *error; NSArray *ipaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YE
for (int i=0; i<[array count]; i++)
{
NSError *error;
NSArray *ipaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *idocumentsDir = [ipaths objectAtIndex:0];
NSString *idataPath = [idocumentsDir stringByAppendingPathComponent:@"File"];
NSLog(@"idataPath:%@",idataPath);
//Create folder here
if (![[NSFileManager defaultManager] fileExistsAtPath:idataPath])
{
[[NSFileManager defaultManager] createDirectoryAtPath:idataPath withIntermediateDirectories:NO attributes:nil error:&error];
}
// Image Download here
NSString *fileName = [idataPath stringByAppendingFormat:@".jpg"];
NSLog(@"imagePathDOWNLOAD:%@",fileName);
_imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[array objectAtIndex:i]]];
[_imgData writeToFile:fileName atomically:YES];
tempImg.image = [UIImage imageWithData:_imgData];
}
为此NSOperationQueue
实现:
UIProgressView *progressView = [[UIProgressView alloc] init];
// configure the progress view and add it to your UI
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i=0; i<[array count]; i++)
{
NSError *error;
NSArray *ipaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *idocumentsDir = [ipaths objectAtIndex:0];
NSString *idataPath = [idocumentsDir stringByAppendingPathComponent:@"File"];
NSLog(@"idataPath:%@",idataPath);
//Create folder here
if (![[NSFileManager defaultManager] fileExistsAtPath:idataPath])
{
[[NSFileManager defaultManager] createDirectoryAtPath:idataPath withIntermediateDirectories:NO attributes:nil error:&error];
}
// Image Download here
NSString *fileName = [idataPath stringByAppendingFormat:@".jpg"];
NSLog(@"imagePathDOWNLOAD:%@",fileName);
_imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[array objectAtIndex:i]]];
[_imgData writeToFile:fileName atomically:YES];
// now dispatch any UI updates back to the main queue
dispatch_async(dispatch_get_main_queue(), ^{
[progressView setProgress: (CGFloat) (i + 1.0) / [array count] animated:YES];
tempImg.image = [UIImage imageWithData:_imgData];
});
}
});
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
UIProgressView *progressView = [self addProgressView];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSInteger downloadSuccessCount = 0;
NSInteger downloadFailureCount = 0;
NSString *idataPath = [self createDownloadPath];
for (int i = 0; i < [array count]; i++)
{
// Image Download here
NSString *filename = [self pathForItem:i array:array folder:idataPath];
NSURL *url = [self urlForItem:i array:array];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
UIImage *image = nil;
if (data)
image = [UIImage imageWithData:data];
if (image) {
downloadSuccessCount++;
[data writeToFile:filename atomically:YES];
} else {
downloadFailureCount++;
}
// now dispatch any UI updates back to the main queue
dispatch_async(dispatch_get_main_queue(), ^{
[progressView setProgress: (CGFloat) (downloadSuccessCount + downloadFailureCount) / [array count] animated:YES];
// update the image in the UI if you want
[UIView transitionWithView:self.imageView duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
tempImg.image = image;
} completion:nil];
});
}
NSLog(@"Completed in %.1f seconds", CFAbsoluteTimeGetCurrent() - start);
});
CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
UIProgressView*progressView=[self addProgressView];
NSOperationQueue*队列=[[NSOperationQueue alloc]init];
queue.maxConcurrentOperationCount=5;
NSString*idataPath=[self-createDownloadPath];
self.downloadsuccescount=0;
self.downloadFailureCount=0;
NSOperation*completionOperation=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@“在%.1f秒内完成”,CFAbsoluteTimeGetCurrent()-开始);
}];
对于(int i=0;i<[数组计数];i++)
{
NSOperation*操作=[NSBlockOperation blockOperationWithBlock:^{
//图片下载
NSString*filename=[self-pathForItem:i数组:数组文件夹:idataPath];
NSURL*url=[self-urlForItem:i数组:数组];
NSData*data=[NSData dataWithContentsOfURL:url];
UIImage*image=nil;
如果(数据)
image=[UIImage-imageWithData:data];
如果(图像)
[数据写入文件:文件名原子:是];
//现在将所有UI更新发送回主队列
[[NSOperationQueue mainQueue]添加操作与块:^{
如果(图像){
self.downloadsuccescount++;
//如果需要,可以在UI中更新图像,尽管这样会减慢速度
[UIView转换WithView:self.imageView持续时间:0.25选项:UIView动画选项转换交叉溶解动画:^{
tempImg.image=图像;
}完成:无];
}
其他的
self.downloadFailureCount++;
[progressView setProgress:(CGFloat)(self.downloadSuccessCount+self.downloadFailureCount)/[array count]动画:是];
}];
}];
[队列添加操作:操作];
[completionOperation addDependency:operation];
}
[队列添加操作:完成操作];
总之,如果您使用NSOperationQueue
(它不仅可以提供并发性,您也可以在GCD并发队列中实现并发性,还可以让您轻松控制并发操作的数量(对于网络操作,您应该将并发操作的数量限制在五个或更少),您将享受到显著的性能优势
正如我所建议的那样,更好的做法是使用AFNetworking,在这种网络中,您不仅可以享受操作队列并发性的好处,还可以享受其他好处。并设置进度标签(即%)@emotality当然可以,但仅当您按顺序进行操作时才可以。但如果您使用的是并发、异步请求(你应该这样做,因为它要快得多),您不能仅使用
for
循环的i
变量来更新进度视图。对于并发请求,您无法保证这些请求将完成的顺序。相反,您必须拥有一些其他类属性来跟踪已完成下载的数量,并在更新t时使用该计数器他是进度视图。Lol对不起,我的意思是为那些搜索我搜索的内容的人。我没有阅读答案或问题,但上面的代码是我搜索的内容。如果其他人也搜索了,他们会帮助他们。谢谢回答!)
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
UIProgressView *progressView = [self addProgressView];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 5;
NSString *idataPath = [self createDownloadPath];
self.downloadSuccessCount = 0;
self.downloadFailureCount = 0;
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Completed in %.1f seconds", CFAbsoluteTimeGetCurrent() - start);
}];
for (int i = 0; i < [array count]; i++)
{
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
// Image Download here
NSString *filename = [self pathForItem:i array:array folder:idataPath];
NSURL *url = [self urlForItem:i array:array];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = nil;
if (data)
image = [UIImage imageWithData:data];
if (image)
[data writeToFile:filename atomically:YES];
// now dispatch any UI updates back to the main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if (image) {
self.downloadSuccessCount++;
// update the image in the UI if you want, though this slows it down
[UIView transitionWithView:self.imageView duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
tempImg.image = image;
} completion:nil];
}
else
self.downloadFailureCount++;
[progressView setProgress: (CGFloat) (self.downloadSuccessCount + self.downloadFailureCount) / [array count] animated:YES];
}];
}];
[queue addOperation:operation];
[completionOperation addDependency:operation];
}
[queue addOperation:completionOperation];
[progressView setProgress: (CGFloat) (i + 1.0) / [array count] animated:YES];
self.progressLabel.text = [NSString stringWithFormat:@"%.0f",self.progressView.progress*100];