1

У меня есть таблицаView и кнопка для обновления ячеек. У ячеек есть изображение, которое загружает NSURLConnection sendAsynchronousRequest. При прокрутке Tableview слишком быстро, а затем нажмите кнопку обновления кнопки -> приложение авария с этим:Ошибка синхронизации асинхронных и синхронизирующих потоков xcode

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 11 beyond bounds for empty array' 

По-моему, это случилось потому, что я пытаюсь обновить таблицу перед асинхронной остановкой. dataSaver - это «кеш» для изображения. он имеет изображение при загрузке ячейки. previewArray - это массив с URL-адресами для асинхронного скачивания изображения. nameArray - массив с именами для ячейки.

Извините за мой noob-код :) Кто-нибудь знает, как исправить эту проблему?

Существует мой код:

- (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

Я думаю (как я прочитал ваш вопрос быстро), необходимо установить

dataSaver = nil;         <-------- Add this line!! 
dataSaver = [[NSMutableArray alloc]init]; 

в методе «- (IBAction) refreshTable: (ID) отправитель "... удача

Смежные вопросы