检测dispatch_async方法是否仍在运行

Gan*_*ham 1 iphone cocoa-touch objective-c grand-central-dispatch ios

我有一个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;
   });
}
Run Code Online (Sandbox Code Playgroud)

单击按钮时,视图将进入屏幕,并显示_storedImages中当前存在的所有图像

- (void)displayImages {
   for (NSString *link in _storedImages) {
      //displayImages
   }
}
Run Code Online (Sandbox Code Playgroud)

此设置的问题是,如果用户在加载所有图像之前单击按钮,则并非所有图像都显示在屏幕上.

因此,如果单击该按钮,我想显示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
Run Code Online (Sandbox Code Playgroud)

rob*_*off 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];
        });

    });
}
Run Code Online (Sandbox Code Playgroud)

所以我们将自己发送addImage:到每个图像的主队列.该addImage:方法只在主线程上调用,因此可以安全地访问storedImages:

- (void)addImage:(UIImage *)image {
    [self.storedImages addObject:image];
    if (storedImagesViewIsVisible) {
        [self updateStoredImagesViewWithImage:image];
    }
}
Run Code Online (Sandbox Code Playgroud)

didFinishLoadingImages当我们加载所有图像时,我们发送自己.在这里,我们可以更新doneLoadingImages标志,并在必要时隐藏进度HUD:

- (void)didFinishLoadingImages {
    self.doneLoadingImages = YES;
    if (storedImagesViewIsVisible) {
        [self hideProgressHUD];
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您的按钮操作可以检查doneLoadingImages属性:

- (IBAction)displayImagesButtonWasTapped:(id)sender {
    if (!storedImagesViewIsVisible) {
        [self showStoredImagesView];
        if (!self.doneLoadingImages) {
            [self showProgressHUD];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)