Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios dispatch_async(dispatch_get_main_queue()不适用于iPad,但适用于iPhone_Ios_Objective C_Iphone_Ipad_Sdwebimage - Fatal编程技术网

Ios dispatch_async(dispatch_get_main_queue()不适用于iPad,但适用于iPhone

Ios dispatch_async(dispatch_get_main_queue()不适用于iPad,但适用于iPhone,ios,objective-c,iphone,ipad,sdwebimage,Ios,Objective C,Iphone,Ipad,Sdwebimage,我正在使用SDWebImage库及其在iPhone上的工作。但我不知道为什么iPad中不调用它。我尝试设置断点,但也没有达到断点。我将此方法放置在cellForItemAtIndexPath中 -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString* cellId

我正在使用SDWebImage库及其在iPhone上的工作。但我不知道为什么iPad中不调用它。我尝试设置断点,但也没有达到断点。我将此方法放置在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;
}

并发映像加载实现中存在问题。当调用
-collectionView:cellForItemAtIndexPath:
时,设备在主队列上执行代码。假设
-downloadImageWithURL:options:progress:completed:
方法在后台线程上执行映像加载并立即返回,我们可以调用它没有
dispatch\u async(dispatch\u get\u main\u queue()…
wrapping。否则我们无法保证完成处理程序在主线程上执行,因此代码应该如下所示

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

iPhone和iPad上的不同结果可以用测试设备技术规格的架构差异来解释。

在并行图像加载实现中存在问题。当调用
-collectionView:cellForItemAtIndexPath:
时,设备在主队列上执行代码。假设e> -downloadImageWithURL:options:progress:completed:方法在后台线程上执行图像加载并立即返回,我们可以调用它而无需
调度\u异步(调度\u获取\u主队列()…
wrapping。否则,我们无法保证完成处理程序在主线程上执行,因此代码应该如下所示

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

iPhone和iPad上的不同结果可以用测试设备技术规格的架构差异来解释。

你的缩进使得你发布的代码几乎无法理解。你说“我把这个方法放在cellForItemAtIndexPath中了。”您发布的不是一个方法,而是一个代码片段。您应该发布整个
cellForItemAtIndexPath
方法,并在发布之前使用conrol-I重新缩进代码。为什么要使用两个嵌套调用来调度\u async,外部调用到全局后台队列,内部调用到主队列?所有这些都可以做到是延迟调用该代码。您实际想用该代码做什么?另外,您知道您的
downloadImageWithURL:options:progress:completed:
方法的完成块是在主线程还是在后台线程上调用的吗?如果在后台线程上调用,那将是一个问题。我已经编辑了我的答案。您的缩进使您发布的代码几乎无法理解。您说“我将此方法放在cellForItemAtIndexPath中。”您发布的不是一个方法,而是一个代码片段。您应该发布整个
cellForItemAtIndexPath
方法,并在发布之前使用conrol-I重新缩进代码。为什么要使用两个嵌套调用来调度\u async,外部调用到全局后台队列,内部调用到主队列?所有这些都可以做到是延迟调用该代码。您实际想用该代码做什么?另外,您知道您的
downloadImageWithURL:options:progress:completed:
方法的完成块是在主线程还是在后台线程上调用的吗?如果在后台线程上调用,那将是一个问题。我已经编辑了我的答案。很好解释。如果不是这样,OP必须更清楚他所说的“…这在iPad中不被称为”是什么意思。很好的解释。如果不是这样,OP必须更清楚他所说的“…这在iPad中不被称为”是什么意思