我正在尝试从 Parse 检索上传的缩略图照片以在 UITableViewCells 中显示它们,但每次都会抛出异常。错误码如下:“Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'”
这是我的代码:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
PFQuery *query = [PFQuery queryWithClassName:@"Events"];
[query orderByDescending:@"date"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"Error: %@ %@", error, [error userInfo]);
} else {
self.events = (NSMutableArray *) objects;
[self.tableView reloadData];
for (PFObject *event in self.events) {
NSInteger index = [self.events indexOfObject:event];
PFFile *imageFile = [event objectForKey:@"thumbnailImage"];
[imageFile getDataInBackgroundWithBlock:^(NSData *result, NSError *error) {
if (error) {
//Handle Error
} else {
UIImage *image = [UIImage imageWithData:result];
if (self.thumbnailPhotos == nil) {
self.thumbnailPhotos = [NSMutableArray array];
self.thumbnailPhotos[index] = image;
} else {
self.thumbnailPhotos[index] = image;
}
[self.tableView reloadData];
}
}];
}
}
}];
CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuseIdentifier = @"Cell";
EventsTableViewCell *cell = (EventsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath];
PFObject *event = [self.events objectAtIndex:indexPath.row];
NSDate *date = [event objectForKey:@"date"];
NSString *dateString = [self.dateFormat stringFromDate:date];
NSString *timeString = [self.timeFormat stringFromDate:date];
NSLog(@"IndexPath.row = %ld", (long)indexPath.row);
if ([self.thumbnailPhotos objectAtIndex:indexPath.row] != nil) {
cell.imageView.image = self.thumbnailPhotos[indexPath.row];
} else {
NSLog(@"Nil, Application will crash!");
}
cell.eventNameLabel.text = [event objectForKey:@"title"];
cell.dateLabel.text = dateString;
cell.timeLabel.text = timeString;
[cell.timeLabel sizeToFit];
return cell;
}`
我必须添加 self.events 的索引值,因为缩略图照片的下载速度不同,所以我的单元格总是显示错误事件的错误照片。 我希望这是足够的细节来解决问题。
最佳答案
应用程序正在崩溃,因为 thumbnailPhotos 在索引处没有任何要分配的对象。请使用以下代码。
更新代码,支持字典保存缩略图
/*
Define events as NSMutableArray which holds all events
Define thumbnailPhotos as NSMutableDictionary which holds thumbnail image for index as key
*/
//Create a weak Reference of self for accessing self within block
__weak __typeof(self)weakSelf = self;
PFQuery *query = [PFQuery queryWithClassName:@"Events"];
[query orderByDescending:@"date"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"Error: %@ %@", error, [error userInfo]);
} else {
//Create a strong reference for updating the UI
__strong __typeof(weakSelf)strongSelf = weakSelf;
//Assign the events to instance object
strongSelf.events = [NSMutableArray arrayWithArray:objects];
//Alloced thumbnail dictionary
strongSelf.thumbnailPhotos = [NSMutableDictionary dictionary];
//Reload tableView so that data will be visible
[strongSelf.tableView reloadData];
for (PFObject *event in strongSelf.events) {
//Define index as block type because we have to use this instance within block
__block NSInteger index = [strongSelf.events indexOfObject:event];
PFFile *imageFile = [event objectForKey:@"thumbnailImage"];
[imageFile getDataInBackgroundWithBlock:^(NSData *result, NSError *error) {
if (error) {
//Handle Error
} else {
UIImage *image = [UIImage imageWithData:result];
//Set the image against index
[strongSelf.thumbnailPhotos setObject:@"" forKey:@(index)];
//Reload only cell for which image is just downloaded
[strongSelf.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}];
}
}
}];
更新: 修改你的 cellForRowAtIndexPath 如下
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuseIdentifier = @"Cell";
EventsTableViewCell *cell = (EventsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath];
PFObject *event = [self.events objectAtIndex:indexPath.row];
NSDate *date = [event objectForKey:@"date"];
NSString *dateString = [self.dateFormat stringFromDate:date];
NSString *timeString = [self.timeFormat stringFromDate:date];
NSLog(@"IndexPath.row = %ld", (long)indexPath.row);
if ([self.thumbnailPhotos valueForKey:@(indexPath.row)]) {
cell.imageView.image = [self.thumbnailPhotos valueForKey:@(indexPath.row)];
} else {
NSLog(@"Nil, Application will crash!");
}
cell.eventNameLabel.text = [event objectForKey:@"title"];
cell.dateLabel.text = dateString;
cell.timeLabel.text = timeString;
[cell.timeLabel sizeToFit];
return cell;
}
在此实现中,缩略图图像被保存到字典中,并且 tableView 的第二次重新加载是基于每个单元格的,而不是重新加载完整的 tableView 来下载单个缩略图。
关于ios - 应用程序因 NSRangeException (NSMutableArray) 而终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32128283/