我正在构建一个应用程序,它将从解析服务器查询一组图像(缩略图),然后在集合视图中显示它们,类似于用户配置文件页面中的instagram操作。我创建了一个成功查询后端数据的方法:
-(void)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:@"VideoApp"];
NSString * author = [[PFUser currentUser] objectForKey:@"FBName"];
[query whereKey:@"author" equalTo:author];
[query orderByAscending:@"createdAt"];
[query setCachePolicy:kPFCachePolicyNetworkOnly];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(@"Successfully retrieved %d objects", objects.count);
[self.collectionView reloadData];
userVideosArray = [[NSMutableArray alloc] initWithCapacity:objects.count];
for (PFObject *object in objects) {
PFFile *thumbnail = [object objectForKey:@"video_thumbnail"];
[thumbnail getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
NSLog(@"Fetching image");
[userVideosArray addObject:[UIImage imageWithData:data]];
} else {
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
}
}
}];
}
此方法从后端成功检索四个对象,并在ViewDidLoad方法中调用。 然后在集合视图cellForRowAtIndexPath方法中,我尝试将查询对象图像设置为collectionviewcell上的UIImageview,如下所示:
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
//CollectionViewcellCollectionViewCell * cell = (CollectionViewcellCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 70, 70)];
imageView.backgroundColor = [UIColor grayColor];
[cell addSubview:imageView];
PFQuery *query = [PFQuery queryWithClassName:@"VideoApp"];
NSString * info = [[PFUser currentUser] objectForKey:@"FBName"];
[query whereKey:@"author" equalTo:info];
imageView.image = [UIImage imageWithData:[userVideosArray objectAtIndex:indexPath.row]];
return cell;
}
我一直在imageView.image = [UIImage imageWithData:[userVideosArray objectAtIndex:indexPath.row]];
上获得NSException。不是100%肯定为什么。有什么想法吗?
答案 0 :(得分:0)
您应该在处理收到的数据后更新collectionView ,而不是之前。您拨打[self.collectionView reloadData]
trickers的电话会调用cellForItemAtIndexPath
,我的猜测是userVideosArray还没有包含您期望的任意数量的项目。
无论如何,崩溃。试试这个来防止崩溃:
if (indexPath.item < userVideosArray.count)
imageView.image = [UIImage imageWithData:userVideosArray[indexPath.item]];
在使用collectionView时,我建议使用item
而不是row
,因为一个collectionView行可能包含多个项目。你现在知道你正在做什么,并且可以使用行,但后来的行与项目术语可能会让人感到困惑。
答案 1 :(得分:0)
你这样做:
1)reloadData
:错误,因为您在执行此操作之前未更新任何数组。我认为它是findObjectsInBackgroundWithBlock
的副作用,这肯定是错误的,因为只有执行reloadData
的对象应该负责更新数据源的数据。
2)初始化userVideosArray
没有任何项目(userVideosArray.count == 0
)。查看您的错误并知道调用cellForItemAtIndexPath
我假设-collectionView:numberOfItemsInSection:
使用其他不同的数组来表示错误的项目数,因为您试图从{{1}获取项目}可能有不同数量的项目
3)在背景中填充userVideosArray
项目。记住1和2可以帮助我们解决您的崩溃问题。在userVideosArray
中,您正在尝试获取仍未加载的项目
顺便说一下:cellForItemAtIndexPath
每次集合视图重复使用时,都会继续向您的单元格添加图片视图