我有一个 loadImages 方法
- (void)loadImages {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//this method loads images from a url, processes them
//and then adds them to a property of its view controller
//@property (nonatomic, strong) NSMutableArray *storedImages;
});
}
单击按钮时,视图将进入屏幕,并显示 _storedImages中当前存在的所有图像
- (void)displayImages {
for (NSString *link in _storedImages) {
//displayImages
}
}
此设置的问题是,如果用户在加载所有图像之前单击按钮,则并非所有图像都显示在屏幕上。
因此,我想显示SVProgressHUD,如果单击该按钮, loadImages dispatch_async方法仍在运行。
那么,如何跟踪此dispatch_async何时完成?因为如果我知道这一点,那么我可以显示SVProgressHUD直到它完成。
在旁注中,如果您知道如何动态加载/显示图像,那么信息也会很有用,即您单击按钮然后当您看到当前图像时,会有更多图像下载并显示
首次感谢iOS开发人员!
好的我找到了一个解决方案,但效率非常低,我相信有更好的方法可以做到这一点
1. Keep a boolean property doneLoadingImages which is set to NO 2. After the dispatch method finishes, set it to YES 3. In the display images method, have a while (self.doneLoadingImages == NO) //display progress HUD until all the images a loaded
答案 0 :(得分:6)
请记住NSMutableArray
不是线程安全的。您必须确保不要一次尝试从两个线程访问它。
使用布尔值来跟踪您是否仍在加载图片。让loadImages
看起来像这样:
- (void)loadImages {
self.doneLoadingImages = NO;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
while (1) {
UIImage *image = [self bg_getNextImage];
if (!image)
break;
dispatch_async(dispatch_get_main_queue(), ^{
[self addImage:image];
});
}
dispatch_async(dispatch_get_main_queue(), ^{
[self didFinishLoadingImages];
});
});
}
所以我们在每个图像的主队列上发送addImage:
。 addImage:
方法只会在主线程上调用,因此可以安全地访问storedImages
:
- (void)addImage:(UIImage *)image {
[self.storedImages addObject:image];
if (storedImagesViewIsVisible) {
[self updateStoredImagesViewWithImage:image];
}
}
当我们加载了所有图片时,我们会发送didFinishLoadingImages
。在这里,我们可以更新doneLoadingImages
标志,并在必要时隐藏进度HUD:
- (void)didFinishLoadingImages {
self.doneLoadingImages = YES;
if (storedImagesViewIsVisible) {
[self hideProgressHUD];
}
}
然后,您的按钮操作可以检查doneLoadingImages
属性:
- (IBAction)displayImagesButtonWasTapped:(id)sender {
if (!storedImagesViewIsVisible) {
[self showStoredImagesView];
if (!self.doneLoadingImages) {
[self showProgressHUD];
}
}
}
答案 1 :(得分:0)
我通常对这类问题所做的基本上是以下(草图):
- (void)downloadImages:(NSArray*)arrayOfImages{
if([arrayOfImages count] != 0)
{
NSString *urlForImage = [arrayOfImages objectAtIndex:0];
// Start downloading the image
// Image has been downloaded
arrayOfImages = [arrayOfImages removeObjectAtIndex:0];
// Ok let's get the next ones...
[self downloadImages:arrayOfImages];
}
else
{
// Download is complete, use your images..
}
}
您可以传递失败的下载次数,甚至可以传递之后接收图像的委托。
答案 2 :(得分:0)
你放了一个“注释”,这可能有所帮助,它允许你显示图像,因为它们下来,我将URL存储在一个数组(这里是字符串,但你可以做NSURL数组)。
for(NSString *urlString in imageURLs)
{
// Add a downloading image to the array of images
[storedImages addObject:[UIImage imageNamed:@"downloading.png"]];
// Make a note of the image location in the array
__block int imageLocation = [storedImages count] - 1;
// Setup the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setTimeoutInterval: 10.0];
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// Check the result
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (data != nil && error == nil && [httpResponse statusCode] == 200)
{
storedImages[imageLocation] = [UIImage imageWithData:data];
[self reloadImages];
}
else
{
// There was an error
recommendedThumbs[imageLocation] = [UIImageimageNamed:@"noimage.png"];
[self reloadImages]
}
}];
}
然后您需要另一种重新加载显示的方法。如果图像在表中,则[[tableview] reloaddata];
-(void)reloadImages