异步和同步线程错误xcode

时间:2014-08-07 07:23:52

标签: xcode uitableview asynchronous nsoperationqueue downloading

我有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;
    }

1 个答案:

答案 0 :(得分:0)

我猜(当我快速阅读你的问题时)你需要设置

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

在方法“ - (IBAction)refreshTable:(id)sender”... 祝你好运