gpt4 book ai didi

ios - 数据源方法 collectionView : numberOfItemsInSection: Crashes App "index 0 beyond bounds for empty array"

转载 作者:行者123 更新时间:2023-11-29 10:43:11 25 4
gpt4 key购买 nike

我整天都在处理这段代码,所以它可能只是我忽略的一些愚蠢的东西,但我似乎无法找出问题所在,而且我无计可施。

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
if(collectionView == self.titleBarCollectionView) {
return 1;
}
NSInteger photoCount = [[self.fetchedResultsController fetchedObjects] count];
NSInteger sectionCount = (photoCount + 3) / 3;
return sectionCount;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
if(collectionView != self.titleBarCollectionView) {
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
NSInteger numberInSection = [sectionInfo numberOfObjects];
if(numberInSection < 3) numberInSection++;
return numberInSection;
}
return 3;
}

我有一个显示用户照片的 UICollectionView。照片取自核心数据,但是 Collection View 中的第一个索引(项目 0,部分 0)被替换为“添加照片”图像,并且所有照片的 indexPaths 都进行了调整以适应这一点。它工作了几个小时都很好,但出于某种原因在删除应用程序(重置核心数据)后,我似乎无法加载 View 。它立即崩溃并显示错误 <strong>* Terminating app due to uncaught exception 'NSRangeException', reason: '*</strong> -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'当它到达 id sectionInfo = [self.fetchedResultsController sections][section]; 行时.我这辈子都弄不明白。这是我的其余数据源方法。

-(void)configureCell:(UICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
if([cell.reuseIdentifier isEqualToString:@"Profile Title Cell"]) {
... Irrelevant code ...
} else if(indexPath.row == 0 && indexPath.section == 0) {
UIImageView *imageView = (UIImageView *)[cell viewWithTag:300];
imageView.image = [UIImage imageNamed:@"plusIcon.png"];
} else {
NSIndexPath *newIndexPath = [self newIndexPathFromIndexPath:indexPath];
Photo *photo = [self.fetchedResultsController objectAtIndexPath:newIndexPath];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:300];

NSData *imageData = [[NSData alloc] initWithBase64EncodedString:photo.thumbnailData options:0];
imageView.image = [UIImage imageWithData:imageData];

if(photo.imageData) {
imageView.image = [UIImage imageWithData:photo.imageData];
} else if(photo.imageURL && ![photo.imageURL isEqualToString:@""]) {
NSString *imageURL = [NSString stringWithFormat:@"%@%@", PHOTOS_BASE_URL, photo.imageURL];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
self.activeThreads += 1;
NSData *imageURLData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
dispatch_async(dispatch_get_main_queue(), ^{
photo.imageData = imageURLData;
[self.imageCollectionView reloadItemsAtIndexPaths:@[indexPath]];
self.activeThreads -= 1;
if(self.activeThreads < 1)
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
});
});
}
}
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = nil;
if(collectionView == self.titleBarCollectionView) {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Profile Title Cell" forIndexPath:indexPath];
} else {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Profile Image Cell" forIndexPath:indexPath];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}

- (NSIndexPath *)newIndexPathFromIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = 0;
NSInteger section = 0;
if(indexPath.row > 0) {
row = indexPath.row - 1;
section = indexPath.section;
} else {
row = 2;
section = indexPath.section - 1;
}
return [NSIndexPath indexPathForItem:row inSection:section];
}

编辑:这是我的 fetchedResultsController setter

- (NSFetchedResultsController *)fetchedResultsController
{
if(!_fetchedResultsController) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];

fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"uploadDate" ascending:YES]];

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"ownerID == %@", self.currentUser.userID];

_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext
sectionNameKeyPath:@"sectionIdentifier"
cacheName:nil];

_fetchedResultsController.delegate = self;

[_fetchedResultsController performFetch:nil];
}
return _fetchedResultsController;
}

最佳答案

您在评论中说 fetchedObjects 返回 8 个对象。在 numberOfSectionsInCollectionView 中,您使用它来计算 Collection View 中的部分数:

NSInteger photoCount = [[self.fetchedResultsController fetchedObjects] count];
NSInteger sectionCount = (photoCount + 3) / 3;
return sectionCount;

假设计数真的是 8,这意味着 sectionCount 是 3(11/3,整数除法)。请注意,您并不是在询问获取的结果 Controller 它有多少个部分,而是在告诉 Collection View 它应该包含三个部分。

由于您在上面返回 3,collectionView:numberOfItemsInSection: 将被调用 3 次,section 值为 0、1 和 2。您将 section 值传递给获取结果 Controller :

id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];

这仅在 fetched results controller 实际上有 3 个部分时有效。 但你从来没有问过它有多少节,所以不能保证它有那么多节。在这种情况下,极有可能发生崩溃。

看起来发生的事情是:

  • 创建抓取结果 Controller 时没有使用sectionNameKeyPath
  • 因此 [self.fetchedResultsController sections] 返回一个空数组
  • 但是您尝试在那个空数组中查找一个对象,因为您假设会有 3 个部分而没有检查这是否属实。

因此你崩溃了。您不能只告诉 fetched results controller 它应该有多少个部分。部分的数量基于获取结果,除非包含 sectionNameKeyPath,否则没有任何部分。

关于ios - 数据源方法 collectionView : numberOfItemsInSection: Crashes App "index 0 beyond bounds for empty array",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23464595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com