我有tableView和按钮来刷新单元格。单元格有图像,由NSURLConnection sendAsynchronousRequest下载。当用户滚动tableView太快然后按下refresh-button - >应用程序崩溃:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 11 beyond bounds for empty array'
在我看来,发生这种情况是因为我尝试在异步停止之前刷新表。
dataSaver
- 图像的“缓存”。当细胞加载时它有图像。
previewArray
- 是带有异步下载映像的URL的数组。
nameArray
- 是包含单元格名称的数组。
抱歉我的noob-code :) 有人知道如何解决这个问题吗?
有我的代码:
- (void)viewDidLoad
{
[super viewDidLoad];
// in this array download image
dataSaver = [[NSMutableArray alloc]init];
// in this array download name
nameArray = [[NSMutableArray alloc]init];
// in this array download urls for image
previewArray = [[NSMutableArray alloc]init];
if (_progressHUD == nil)
{
_progressHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
_progressHUD.labelText = @"Loading...";
_progressHUD.dimBackground = YES;
}
NSOperationQueue *Imagequeue = [[NSOperationQueue alloc]init];
NSInvocationOperation *dataforCategories = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(webService) object:nil];
[Imagequeue addOperation:dataforCategories];
}
// function to parse json and take url (preview) for image to async download and name for cell
-(void)webService{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:[[myUrl stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] ]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
[request setHTTPMethod:@"POST"];
NSURLResponse *urlResponse ;
NSError *requestError;
NSData *responseData =[NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError ];
if(responseData ==nil){
if(requestError !=nil){
NSLog(@"Error=%@",requestError);
}
}
else{
@try {
// ……
// Here is loading data
[previewArray addObject: [self compareStringField:eachProduct[@"preview"]]];
[nameArray addObject: [self compareStringField:eachProduct[@"name"]]];
[[NSOperationQueue mainQueue] addOperationWithBlock:^(void){
[tableVieww reloadData];
[self hideProgressHUD];
}];
}
@catch (NSException *exception) {
NSLog(@"%@",exception);
}
}
}
-(void) hideProgressHUD{
if (_progressHUD){
[_progressHUD hide:YES];
[_progressHUD removeFromSuperview];
_progressHUD = nil;
}
}
- (IBAction) refreshTable:(id)sender
{
if (_progressHUD == nil)
{
_progressHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
_progressHUD.labelText = @"Loading...";
_progressHUD.dimBackground = YES;
}
// alloc arrays.
nameArray = [[NSMutableArray alloc]init];
previewArray = [[NSMutableArray alloc]init];
dataSaver = [[NSMutableArray alloc]init];
// next loading data to refresh
[self performSelectorOnMainThread:@selector(webService) withObject:nil waitUntilDone:YES];
[tableVieww reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"Cell";
MyCell *listCell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (listCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil];
listCell = [nib objectAtIndex:0];
}
listCell.selectionStyle = UITableViewCellSelectionStyleNone;
NSString *imageString=[previewArray objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:[imageString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// fill dataSaver to know if it was already use
listCell.imageView.image = nil;
if ([dataSaver count] != [nameArray count])
for (int f = 0; f < [nameArray count]; f++)
[dataSaver addObject:@" "];
// download image if dataSaver object is empty
if ([[dataSaver objectAtIndex:indexPath.row] isEqual: @" "])
{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if (data == nil || [data isEqual:@"null"] || [data isEqual:@"-"] || [data isEqual:@""] || [data isEqual:@"<null>"] || [data isEqual:@"(null)"] || data == (id)[NSNull null])
[dataSaver replaceObjectAtIndex:indexPath.row withObject:@""];
else
[dataSaver replaceObjectAtIndex:indexPath.row withObject:data];
UIImage *imagemain=[UIImage imageWithData:[dataSaver objectAtIndex:indexPath.row]];
MyCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
{
updateCell.imageView.image = imagemain;
}
}];
}
else
{
UIImage *imagemain=[UIImage imageWithData:[dataSaver objectAtIndex:indexPath.row]];
listCell.imageView.image=imagemain;
}
return listCell;
}
答案 0 :(得分:0)
我猜(当我快速阅读你的问题时)你需要设置
dataSaver = nil; <-------- Add this line!!
dataSaver = [[NSMutableArray alloc]init];
在方法“ - (IBAction)refreshTable:(id)sender”... 祝你好运