AFNetworking和Collection View阻止主线程

时间:2016-03-13 21:52:33

标签: uiimageview uicollectionview afnetworking grand-central-dispatch realm

使用AFNetworking和集合视图时遇到一些麻烦。我正在使用AFNetworking拨打Foursquare的照片API。我构建了从Foursquare给我的照片URL,并将该URL存储在realm.io中。然后,我从领域调用foursquare URL,并在我的集合视图cellForItemAtIndexPath中的AFNetworking的setImageWithURL方法中使用这些URL。当视图控制器在最初加载时,它似乎暂时阻塞主线程(大约1秒),直到图像开始显示在我的集合视图上。我不确定为什么,并且想知道是否有人建议提高性能?提前谢谢!

以下是cellForItemAtIndexPath下面的代码:

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

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *wineryImageView = (UIImageView *)[cell viewWithTag:100];

_photo = [_wineryPhotosArray objectAtIndex:indexPath.row];

[wineryImageView setImageWithURL:[NSURL URLWithString:_photo.photoURLString] placeholderImage:[UIImage imageNamed:@"Grapes"]];

return cell;
} 

_wineryPhotosArray是我的领域数组,其中包含来自Foursquare的照片网址。另外,我尝试在setImageWithURL中包装dispatch_async(dispatch_get_main_que)方法,但这似乎没什么用。

这是我的Foursquare Photo API调用的代码,然后将URL存储在领域中:

 -(void)getFoursquarePhotos {

FoursquarePhotosAPI *foursquarePhotoAPI = [FoursquarePhotosAPI initWithClientSecret:_clientSecret clientID:_clientId venueId:_venueId];

[foursquarePhotoAPI foursquarePhotosAPI:^(NSDictionary *data) {

    for (NSDictionary *foursquarePhotos in data) {

        _photo = [Photo initWithPrefix:[foursquarePhotos valueForKey:@"prefix"] size:[NSString stringWithFormat:@"%@x%@", [foursquarePhotos valueForKey:@"height"], [foursquarePhotos valueForKey:@"width"]] suffix:[foursquarePhotos valueForKey:@"suffix"]wineryId:_venueId];

        RLMRealm *realm = [RLMRealm defaultRealm];
        [realm beginWriteTransaction];
        [realm addOrUpdateObject:_photo];
        [realm commitWriteTransaction];
        [self.collectionView reloadData];
    }
  }];  
}

1 个答案:

答案 0 :(得分:0)

Aaron绝对是正确的,将beginWriteTransactioncommitWriteTransaction拉出for循环可以提高性能。 Realm的一般经验法则是尝试在一次写入事务中尽可能多地批量写入操作。

除此之外,我感觉您不可接受的滚动性能的原因是,您将要下载的图像数据在您将它们添加到各自的图像视图后在主线程上进行解码。

图像在调用[UIImageView setImage:]时未被解码,但在视图即将由GPU渲染时由Core Animation延迟加载(因此将该代码封装在{ {1}}无法做任何事情。)

根据this Stack Overflow answer,AFNetworking的dispatch_async下载类别非常简单,并且本身并没有执行此背景图像解码,但它提出了几种解决方案,例如UIImageAFImageRequestOperation

有关iOS图像解码/渲染管道的更多信息,我建议您观看WWDC 2014视频:iOS应用的高级图形和动画。 :)