[英]How To Update ProgressView in Async Thread
在iOS中,我對GCD和隊列的組合幾乎沒有疑問。 讓我把這些放在這里
第一。 根據IOS6編程cookbook,這里是使用異步和同步下載圖像的小代碼片段。 及其如下
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_async (concurrentQueue, ^ {
UIImage *image = nil;
dispatch_sync(concurrentQueue, ^ { /* download image here */ });
dispatch_sync(dispatch_get_main_queue, ^ { /* show the downloaded image here */ });
});
第二。 我需要從Url下載一些圖像,同時我需要更新進度視圖,顯示已下載了多少圖像。 所以我使用下面的代碼片段
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async (concurrentQueue, ^ { dispatch_sync(dispatch_get_main_queue, ^ { /* download image here and update progress view here */ });
});
請注意,我正在更新主線程上的進度視圖。 但是在下載完所有圖像后,我的進度視圖會顯示出來。 我檢查了其他鏈接,但不清楚答案。沒有得到問題的原因。 我的代碼如下。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{dispatch_sync(dispatch_get_main_queue(), ^{
alert = [[UIAlertView alloc] initWithTitle:@"Please Wait Downloading reports..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] ;
prgView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
prgView.frame = CGRectMake(10, 50, 270, 20);
[alert addSubview:prgView];
[alert show];
prgView.progress=0.0;
actual= 0.0;
for(NSInteger i=0; i<[fileLinks count];i++)
{
// [self downLoadFileFromUrl : fileLinks[i]: i ];
NSLog(@"Url is %@", fileLinks[i]);
NSLog(@"i value is %d", i);
NSData *imagedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileLinks[i]]];
NSString * _filename= [fileLinks[i] lastPathComponent];
NSMutableString *filePath = [[NSMutableString alloc] initWithFormat:@"%@", [VSCore getTempFolder]];
[filePath appendString: _filename] ;
[imagedata writeToFile: filePath atomically:YES];
prgView.progress =((float) i /([fileLinks count]));
NSLog(@" progress value is %f", prgView.progress);
}
});
});
那么這里有什么問題? 而另一個疑問是,如果任何人想要在執行長處理任務時持有用戶(顯示進度視圖或活動指示符),他們不能在主線程中這樣做嗎? (如果他們正在顯示進度條或活動指示符),為什么我們必須使用異步,同步和並發線程或主線程等的組合等。
我有點困惑,因為我必須使用異步,同步,主隊列,並發隊列,串行隊列的正確組合。 如果任何一個給我解釋我或提供了良好的鏈接,了解異步,同步和3隊列的組合。 那挺棒的。
您應該在主隊列上創建和更新“UIProgressView”
並在另一個隊列(不是主隊列)上工作
在做你的工作時,如果你想更新GUI上的任何對象,你應該在主隊列上進行
你可以這樣做:
alert = [[UIAlertView alloc] initWithTitle:@"Please Wait Downloading reports..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] ;
prgView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
prgView.frame = CGRectMake(10, 50, 270, 20);
[alert addSubview:prgView];
[alert show];
prgView.progress=0.0;
actual= 0.0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for(NSInteger i=0; i<[fileLinks count];i++)
{
// [self downLoadFileFromUrl : fileLinks[i]: i ];
NSLog(@"Url is %@", fileLinks[i]);
NSLog(@"i value is %d", i);
NSData *imagedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileLinks[i]]];
NSString * _filename= [fileLinks[i] lastPathComponent];
NSMutableString *filePath = [[NSMutableString alloc] initWithFormat:@"%@", [VSCore getTempFolder]];
[filePath appendString: _filename] ;
[imagedata writeToFile: filePath atomically:YES];
dispatch_async(dispatch_get_main_queue(), ^{
prgView.progress =((float) i /([fileLinks count]));
});
NSLog(@" progress value is %f", prgView.progress);
}
});
你可以閱讀一本電子書:“Pro.Multithreading.and.Memory.Management.for.iOS.and.OS.X”(買或問gg)
祝好運!
異步和同步的組合是正確的,但主線程和其他線程的組合導致循環,特別是在使用同步主線程的異步線程中。
如果你仔細看看你的代碼,你會注意到你實際上正在運行主線程中的所有內容。
^{dispatch_sync(dispatch_get_main_queue(), ^{
alert = [[UIAlertView alloc] initWithTitle:@"Please Wait Downloading reports..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] ;
prgView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
prgView.frame = CGRectMake(10, 50, 270, 20);
[alert addSubview:prgView];
[alert show];
prgView.progress=0.0;
actual= 0.0;
for(NSInteger i=0; i<[fileLinks count];i++)
{
// [self downLoadFileFromUrl : fileLinks[i]: i ];
NSLog(@"Url is %@", fileLinks[i]);
NSLog(@"i value is %d", i);
NSData *imagedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileLinks[i]]];
NSString * _filename= [fileLinks[i] lastPathComponent];
NSMutableString *filePath = [[NSMutableString alloc] initWithFormat:@"%@", [VSCore getTempFolder]];
[filePath appendString: _filename] ;
[imagedata writeToFile: filePath atomically:YES];
prgView.progress =((float) i /([fileLinks count]));
NSLog(@" progress value is %f", prgView.progress);
}
});
這將運行downloadFileFromUrl並更新主線程中的進度視圖(除非downloadFileFromUrl是異步操作,我不知道)
基本上你需要在輔助線程中運行downloadFileFromUrl方法,然后只在主線程上運行這個位:prgView.progress =((float)i /([fileLinks count]));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.