0

I am a beginner in iPhone programming... I have an application that's like a photo gallery where I am loading the images and title for each cell in the UITableView using a server with JSON. When I scroll the table the program crashes!

-(NSInteger) tableView : (UITableView *) tableView numberOfRowsInSection:(NSInteger) section {
    return [id_arr count];

}

-(CGFloat) tableView : (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {
    return 80;
}

//
// tableView:cellForRowAtIndexPath:
//
// Returns the cell for a given indexPath.
//
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];


    }

    NSString *tmp3=[NSString stringWithFormat:@"%@",[path_arr objectAtIndex:indexPath.row]];
    tmp3=[tmp3 stringByReplacingOccurrencesOfString:@"(" withString:@""];
    tmp3=[tmp3 stringByReplacingOccurrencesOfString:@")" withString:@""];
    tmp3=[tmp3 stringByReplacingOccurrencesOfString:@" " withString:@""];
    tmp3=[tmp3 stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    NSLog(@"URL:%@",tmp3);


    NSData *imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:tmp3]];

    //NSLog(@"Image DATA:%@",[path_arr objectAtIndex:0]);
    UIImage* image1 = [[UIImage alloc] initWithData:imageData];
    UIImageView *imgview=[[UIImageView alloc]initWithImage:image1];
    imgview.frame=CGRectMake(5, 5, 56, 68);
    imgview.backgroundColor=[UIColor redColor];
    [cell.contentView addSubview:imgview];


    UILabel *lbl_desc=[[UILabel alloc]initWithFrame:CGRectMake(70, 1, 240, 50)];
    NSString *tmp=[NSString stringWithFormat:@"%@",[descrip_arr objectAtIndex:indexPath.row]];
    tmp=[tmp stringByReplacingOccurrencesOfString:@"(" withString:@""];
    tmp=[tmp stringByReplacingOccurrencesOfString:@")" withString:@""];
    tmp=[tmp stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    //tmp=[tmp stringByReplacingOccurrencesOfString:@" " withString:@""];
    lbl_desc.text=tmp;
    lbl_desc.font=[UIFont systemFontOfSize:14];
    lbl_desc.lineBreakMode=UILineBreakModeWordWrap;
    lbl_desc.numberOfLines=0;
    lbl_desc.textAlignment=UITextAlignmentLeft;
    lbl_desc.backgroundColor=[UIColor clearColor];
    [cell.contentView addSubview:lbl_desc];


    NSLog(@"A_count:%@",[count_arr objectAtIndex:0]);
    UILabel *lbl_page=[[UILabel alloc]initWithFrame:CGRectMake(230, 50, 100, 20)];
    NSString *tmp1=[NSString stringWithFormat:@"%@",[count_arr objectAtIndex:indexPath.row]];
    NSLog(@"A_count1:%@",tmp1);
    tmp1=[tmp1 stringByReplacingOccurrencesOfString:@"(" withString:@""];
    tmp1=[tmp1 stringByReplacingOccurrencesOfString:@")" withString:@""];
    tmp1=[tmp1 stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    tmp1=[tmp1 stringByAppendingString:@"  Images"];
    NSLog(@"A_count123:%@",tmp1);
    lbl_page.text=tmp1;
    lbl_page.font=[UIFont systemFontOfSize:12];
    lbl_page.lineBreakMode=UILineBreakModeWordWrap;
    lbl_page.numberOfLines=0;
    lbl_page.textAlignment=UITextAlignmentLeft;
    lbl_page.backgroundColor=[UIColor clearColor];
    [cell.contentView addSubview:lbl_page];

    cell.backgroundColor=[UIColor clearColor];

    [imageData release];
    [image1 release];
    [imgview release];
}
theChrisKent
  • 15,029
  • 3
  • 61
  • 62
user569379
  • 191
  • 1
  • 1
  • 6
  • Without posting any code, I'd say the answer is definitely "No. Nobody can tell you what the problem is." – kubi Mar 15 '11 at 13:22
  • 1
    No, we can't. We're glad you apparently have telepathy sending powers, but I have to break it to you that everyone else doesn't have the requisite telepathy receiving powers. – occulus Mar 15 '11 at 13:23
  • hi i dont know from which part of the code i am getting that problem.. – user569379 Mar 15 '11 at 13:33
  • can i paste the code under the viewdidload()?? – user569379 Mar 15 '11 at 13:35
  • @user569379 you can edit your question and add whatever code or other information you think might be helpful. I would guess the viewDidLoad probably won't be the problem since the error occurs on scroll. I would post all of your tableview delegate methods (Be sure to put all code in a code block - use the {} button). Also you should debug your app to try and narrow down where the problem occurs. A guide to doing that can be found [here](http://iphonedevelopment.blogspot.com/2009/03/debugging.html) but, in the meantime, go ahead and add the code. – theChrisKent Mar 15 '11 at 13:38
  • please post the error message – vikingosegundo Mar 15 '11 at 13:50
  • @user569379 Thanks for posting your code. It would be nice to see the error message you are receiving when in debug. However, I think the problem lay in your `tableView:cellForRowAtIndexPath:` method and I have posted fixed code below. If this doesn't fix the problem, then we will definitely need that error message. As a side note, when a correct answer gets posted you need to accept it. Please go back and do this on your previous questions, thanks. – theChrisKent Mar 15 '11 at 14:13

3 Answers3

2

You should return cell; at the end of the function.

mvds
  • 45,755
  • 8
  • 102
  • 111
1

You should add the cell controls during the cell initialization and then customize the values for each one using viewWithTag:

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        cell.backgroundColor=[UIColor clearColor];

        UIImageView *imgview=[[UIImageView alloc] init];
        imgview.frame = CGRectMake(5, 5, 56, 68);
        imgview.backgroundColor=[UIColor redColor];
        imgview.tag = 1;
        [cell.contentView addSubview:imgview];
        [imgview release];

        UILabel *lbl_desc=[[UILabel alloc] initWithFrame:CGRectMake(70, 1, 240, 50)];
        lbl_desc.font=[UIFont systemFontOfSize:14];
        lbl_desc.lineBreakMode = UILineBreakModeWordWrap;
        lbl_desc.numberOfLines = 0;
        lbl_desc.textAlignment = UITextAlignmentLeft;
        lbl_desc.backgroundColor = [UIColor clearColor];
        lbl_desc.tag = 2;
        [cell.contentView addSubview:lbl_desc];
        [lbl_desc release];

        UILabel *lbl_page=[[UILabel alloc] initWithFrame:CGRectMake(230, 50, 100, 20)];
        lbl_page.font=[UIFont systemFontOfSize:12];
        lbl_page.lineBreakMode = UILineBreakModeWordWrap;
        lbl_page.numberOfLines = 0;
        lbl_page.textAlignment = UITextAlignmentLeft;
        lbl_page.backgroundColor = [UIColor clearColor];
        lbl_page.tag = 3
        [cell.contentView addSubview:lbl_page];
        [lbl_page release];
    }

    NSMutableString *tmp3 = [NSString stringWithFormat:@"%@",[path_arr objectAtIndex:indexPath.row]];
    [tmp3 replaceOccurrencesOfString:@"(" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp3 length])];
    [tmp3 replaceOccurrencesOfString:@")" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp3 length])];
    [tmp3 replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp3 length])];
    [tmp3 replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp3 length])];
    NSLog(@"URL:%@",tmp3);    

    UIImageView* imgView = (UIImageView *)[cell viewWithTag:1];
    imgView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:tmp3]]];

    NSMutableString *tmp = [NSString stringWithFormat:@"%@",[descrip_arr objectAtIndex:indexPath.row]];
    [tmp replaceOccurrencesOfString:@"(" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp length])];
    [tmp replaceOccurrencesOfString:@")" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp length])];
    [tmp replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp length])];
    [tmp replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp length])];
    UILabel *lblDesc = (UILabel *)[cell viewWithTag:2];
    lblDesc.text = tmp;

    NSLog(@"A_count:%@",[count_arr objectAtIndex:0]);

    NSMutableString *tmp1=[NSString stringWithFormat:@"%@",[count_arr objectAtIndex:indexPath.row]];
    NSLog(@"A_count1:%@",tmp1);
    [tmp1 replaceOccurrencesOfString:@"(" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp1 length])];
    [tmp1 replaceOccurrencesOfString:@")" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp1 length])];
    [tmp1 replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:NSMakeRange(0,[tmp1 length])];
    [tmp1 appendString:@"  Images"];
    NSLog(@"A_count123:%@",tmp1);
    UILabel *lblPage = (UILabel *)[cell viewWithTag:3];
    lblPage.text = tmp1;

    return cell;
}

In the above code I have moved all universal (to the table) control creation/setup to the cell initialization so that it is only done once (since cells are reused). I then reference these controls using the custom tag assigned to each of them. I have also added proper release statements for your controls, removed the unnecessary allocation of UIImage and NSData, and changed your strings to mutable ones to make all that customization easier and more performant. You were also failing to return the cell, so I have added that as the final line of this method.

I have left your image retrieval code in tact, but as deanWombourne has pointed out, retrieving this here is a terrible plan further complicated because there is no validation that data was received. You will want to implement a background thread that downloads those images one at a time to a temporary cache. Then in the above method you can pull those images from that cache rather than fetching them each time (see this question for more information: Cache URL images iphone UITableview)

Community
  • 1
  • 1
theChrisKent
  • 15,029
  • 3
  • 61
  • 62
1

OK, perhaps not an answer per se but this line worries me :

NSData *imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:tmp3]];

you're loading data synchrounousl;y each time a new cell appears i.e. each time you scroll the table?

And you're nto checking the return value of this - what if this request fails - you will end up with nil as imagedata nd that can't be good.

You need to load the image data in a background thread using NSURLConnection asynchronously and you definitely need to check that you got read image data back from the server!

deanWombourne
  • 38,189
  • 13
  • 98
  • 110