简体   繁体   中英

dispatch_async(dispatch_get_main_queue() is not working on iPad, but working on iPhone

I am using SDWebImage library and its working on iPhone. But I don't know why this is not called in iPad. I tried to put break points, but it doesn't hit the break point either. I put this method in cellForItemAtIndexPath.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString* cellIdentifier = @"CustomCollectionViewCell";
     CustomCollectionViewCell* cell = (CustomCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
     [cell.downloadButton setTag:indexPath.row];
     [cell.downloadButton addTarget:self action:@selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
     catalogModel = [catalogArray objectAtIndex:indexPath.item];
     cell.cellDescription.text = catalogModel.catalogName;
     SDWebImageManager *manager = [SDWebImageManager sharedManager];
     NSString *urlStr = catalogModel.imageNameThumbnail;
     NSURL *url = [NSURL URLWithString:urlStr];
     dispatch_async(dispatch_get_main_queue(), ^{
             if ([self.catalogCollectionView.indexPathsForVisibleItems containsObject:indexPath])
             {
                  catalogModel = [catalogArray objectAtIndex:indexPath.item];
                  [manager downloadImageWithURL:[NSURL URLWithString:catalogModel.imageNameThumbnail] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {}completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL)
                  {
                       cell.cellImageView.image = image;
                       NSLog(@"%@",catalogModel.catalogName);
                  }];
             };

        });
     return cell;
}

There is a problem in concurrent image loading implementation. When -collectionView: cellForItemAtIndexPath: is calling, the device executes code on the main queue. Assuming that -downloadImageWithURL:options:progress:completed: method performs image loading on the background thread and returns instantly we can call it without dispatch_async(dispatch_get_main_queue()... wrapping. Otherwise we cannot guarantee that the completion handler is executing on the main thread, so the code should look like this

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString* cellIdentifier = @"CustomCollectionViewCell";

     CustomCollectionViewCell* cell = (CustomCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

     ...

     SDWebImageManager *manager = [SDWebImageManager sharedManager];

     // methods with completion block usually return instantly
     [manager downloadImageWithURL:aURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize){} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
         // ensure ui is updating on main thread and for visible cell
         dispatch_async(dispatch_get_main_queue(), ^{
             if ([collectionView.indexPathsForVisibleItems containsObject:indexPath]) {
                 cell.cellImageView.image = image;
             }
         });
     }];

     return cell;
}

And the different results on iPhone and iPad can be explained by the architectural differences in technical specifications of testing devices.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM