簡體   English   中英

檢測dispatch_async方法是否仍在運行

[英]Detect if a dispatch_async method is still running

我有一個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
   }
}

此設置的問題是, 如果用戶在加載所有圖像之前單擊該按鈕,則不是所有圖像都顯示在屏幕上。

因此, 如果單擊按鈕,並且loadImages dispatch_async方法仍在運行 ,我想顯示SVProgressHUD

那么, 如何跟蹤此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 

請記住, 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];
        }
    }
}

我通常對這種問題所做的基本上是以下內容(粗略的草圖):

- (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..
  }
}

您可以傳遞失敗的下載次數,甚至可以傳遞將在之后接收圖像的委托。

您放置一個“注釋”,這可能會有所幫助,它允許您在圖像下降時顯示它們,我將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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM