EXC_BAD_ACCESS when I scroll my view

2019-09-19 17:18发布

问题:

I have two views: the first one is a UITableView in plain style (created programmatically); the second one is a UIScrollView that contains an image and a UITableView in grouped style (also created programmatically).

When I navigate from the firstView -> secondView everything works fine. However if I come back to the firstView and then I try to navigate firstView ->secondView for the second time, I get a EXC_BAD_ACCESS error.

UPDATE

This is the code of the UITableView delegate in the secondView:

-
 (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    switch (section) {
        case 0: 

        //header - breve descrizione
        return 2;

        break;
    case 1: //mappa

        //header - mappa statica (immagine) - footer (indirizzo)
        return 3;

        break;
    case 2: //review

        //header - prima review
        return 2;

        break;
    default:
        return 0;

        break;


 }

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    switch (indexPath.section) {
        case 0:
            switch (indexPath.row) {
                case 0: //case titolo (header)


    return HTABLE_DESCR_HEADER;
                    break;

                case 1: //case corpo
                    return HTABLE_DESCR_BODY;
                    break;

                default:
                    return 0;
                    break;
            }
            break;
        case 1:

            switch (indexPath.row) {
                case 0: //case titolo (header)
                    return HTABLE_LOC_HEADER;
                    break;

                case 1: //case corpo
                    return HTABLE_LOC_BODY;
                    break;

                case 2: //case footer 
                    return HTABLE_LOC_FOOTER;
                    break;

                default:
                    return 0;
                    break;
            }

            break;
        case 2:

            switch (indexPath.row) {
                case 0: //case titolo (header)
                    return HTABLE_REV_HEADER;
                    break;

                case 1: //case corpo
                    return HTABLE_REV_BODY;
                    break;

                default:
                    return 0;
                    break;
            }

            break;
        default:            
            return 0;
            break;
    }

}

/*- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

 return @"Travellers Guide";

 }*/

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    int section = 2;

    //se ci sono review
    if ([[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"list_review"] count] > 0) {
        section++;
    }

    return section;

}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [self getCellContentView:CellIdentifier];
    }    

    cell.accessoryType = UITableViewCellAccessoryNone;

    cell.selectionStyle = UITableViewCellSelectionStyleGray;

    switch (indexPath.section) {
        case 0: //descrizione

            switch (indexPath.row) {
                case 0: //header

                    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"language"] isEqualToString:@"it"]) {
                        cell.textLabel.text = @"Descrizione";
                    } else {
                        cell.textLabel.text = @"Description";
                    }
                    cell.textLabel.backgroundColor = [UIColor clearColor];
                    cell.textLabel.textColor = [UIColor blackColor];
                    cell.textLabel.shadowColor = [UIColor whiteColor];
                    cell.textLabel.shadowOffset = CGSizeMake(1, 1);
                    cell.textLabel.highlightedTextColor = [UIColor blackColor];
                    cell.textLabel.font = [UIFont boldSystemFontOfSize:11.0];
                    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"rigaDescrHeader.png"]];

                    break;

                case 1: //descrizione

                    NSLog(@"Descr");

                    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"rigaRevBody.png"]];
                    cell.textLabel.text = [[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"description"];
                    cell.textLabel.font = [UIFont systemFontOfSize:10.0];
                    cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;
                    cell.textLabel.numberOfLines = 3;
                    cell.textLabel.textColor = [UIColor blackColor];
                    cell.textLabel.backgroundColor = [UIColor clearColor];
                    cell.textLabel.shadowColor = [UIColor whiteColor];
                    cell.textLabel.shadowOffset =CGSizeMake(1, 1);
                    cell.textLabel.highlightedTextColor = [UIColor blackColor];

                    break;

                default:
                    break;
            }

            break;
        case 1: //mappa

            //header - mappa statica (immagine) - footer (indirizzo)
            switch (indexPath.row) {
                case 0: //header

                    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"language"] isEqualToString:@"it"]) {
                        cell.textLabel.text = @"Posizione";
                    } else {
                        cell.textLabel.text = @"Location";
                    }
                    cell.textLabel.font = [UIFont boldSystemFontOfSize:11.0];
                    cell.textLabel.backgroundColor = [UIColor clearColor];
                    cell.textLabel.textColor = [UIColor blackColor];
                    cell.textLabel.shadowColor = [UIColor whiteColor];
                    cell.textLabel.shadowOffset = CGSizeMake(1, 1);
                    cell.textLabel.highlightedTextColor = [UIColor blackColor];
                    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"rigaLocHeader.png"]];

                    break;

                case 1: //mappa

                    NSLog(@"Mappa");

                    CLLocationDegrees latitude  = [[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"latitude"] doubleValue];
                    CLLocationDegrees longitude = [[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"longitude"] doubleValue];
                    CLLocation* poiLocation = [[[CLLocation alloc] initWithLatitude:latitude longitude:longitude] autorelease];
                    Annotation *ann = [Annotation annotationWithCoordinate:poiLocation.coordinate];
                    //mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, HTABLE_LOC_BODY)];
                    [mapView setHidden:NO];
                    [mapView addAnnotation:ann];
                    MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
                    region.center = poiLocation.coordinate;                    
                    region.span.longitudeDelta = 0.05f;
                    region.span.latitudeDelta  = 0.05f;
                    [self.mapView setRegion:region animated:YES];
                    [self.mapView regionThatFits:region];
                    cell.backgroundView = mapView;


                    UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 302, 120)]; 
                    imgView.image = [UIImage imageNamed:@"ombraMappa.png"];
                    [cell.backgroundView addSubview:imgView];
                    [imgView release];

                    break;

                case 2: //footer

                    cell.textLabel.text = [[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"locality"];
                    cell.textLabel.font =[UIFont systemFontOfSize:10.0];
                    cell.textLabel.backgroundColor = [UIColor clearColor];
                    cell.textLabel.textColor = [UIColor blackColor];
                    cell.textLabel.shadowColor = [UIColor whiteColor];
                    cell.textLabel.shadowOffset = CGSizeMake(1, 1);
                    cell.textLabel.highlightedTextColor = [UIColor blackColor];

                    cell.detailTextLabel.text = [[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"address"];
                    cell.detailTextLabel.font = [UIFont boldSystemFontOfSize:9.0];
                    cell.detailTextLabel.textColor = [UIColor grayColor];
                    cell.detailTextLabel.backgroundColor = [UIColor clearColor];
                    cell.detailTextLabel.shadowColor = [UIColor whiteColor];
                    cell.detailTextLabel.shadowOffset = CGSizeMake(1, 1);
                    cell.detailTextLabel.highlightedTextColor = [UIColor blackColor];
                    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"rigaLocFooter.png"]];

                    break;

                default:
                    break;
            }

            break;
        case 2: //review

            //header - mappa statica (immagine) - footer (indirizzo)
            switch (indexPath.row) {
                case 0: //header

                    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"language"] isEqualToString:@"it"]) {
                        cell.textLabel.text = [NSString stringWithFormat:@"Recensioni (%d)",[[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"list_review"] count]];
                    } else {
                        cell.textLabel.text = [NSString stringWithFormat:@"Review (%d)",[[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"list_review"] count]];
                    }
                    cell.textLabel.font = [UIFont boldSystemFontOfSize:11.0];
                    cell.textLabel.backgroundColor = [UIColor clearColor];
                    cell.textLabel.textColor = [UIColor blackColor];
                    cell.textLabel.shadowColor = [UIColor whiteColor];
                    cell.textLabel.shadowOffset = CGSizeMake(1, 1);
                    cell.textLabel.highlightedTextColor = [UIColor blackColor];

                    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"rigaLocHeader.png"]];

                    break;

                case 1: //review

                    cell.textLabel.text = [[[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:@"list_review"] objectAtIndex:0] objectForKey:@"review"];
                    cell.textLabel.font =[UIFont systemFontOfSize:10.0];
                    cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;
                    cell.textLabel.numberOfLines = 3;
                    cell.textLabel.backgroundColor = [UIColor clearColor];
                    cell.textLabel.textColor = [UIColor blackColor];
                    cell.textLabel.shadowColor = [UIColor whiteColor];
                    cell.textLabel.shadowOffset = CGSizeMake(1, 1);
                    cell.textLabel.highlightedTextColor = [UIColor blackColor];
                    cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"rigaRevBody.png"]];

                    break;

                default:
                    break;
            }

            break;
        default:                
            break;
    }

    return cell;

}


- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {

    UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];

    return cell;
}

回答1:

The EXC_BAD_ACCESS isn't caused by the progression of one view to the next. Rather, it will be properties of those views, or the creation and release - or not - of the view objects themselves that are to blame.

Your first step is to run the Analyzer. Then, if you've fixed all that and theres still a problem, start running the Leaks tool in Instruments.

For more details on resolving EXC_BAD_ACCESS issues, along with the excellent link on what causes these errors and step by step instructions for how to fix, have a look at answers to these questions:

finding reason for EXC_BAD_ACCESS - in Xcode4

Random EXC_BAD_ACCESS in a place that it cannot happen

In your case, I'd specifically look at how you are creating secondView, and what you do with firstView when you return to secondView.



回答2:

I just spent a week tracking down a EXC_BAD_ACCESS problem in a large app that worked fine before converting it to ARC. I would get the EXC_BAD_ACCESS on the closing bracket of a "switch" construct. Yet NSZombieEnabled and the various Instrument settings would not detect anything for me.

What fixed it was putting curlies around the case's that made the difference. I did it for each of them, though perhaps it was critical for only some, i.e.

Before:

case ...:
 stmt;
 stmt;
 break;

After:

case ...:{
 stmt;
 stmt;
 }break;

This fixed the problem in two places within a large app for me. I know that I read something somewhere about ARC and switch/case (and maybe someone can add a link to it), but I don't understand the theory behind why this happened and why this fix worked. Perhaps someone could explain. (Later: after reading the following reference at openradar, it all makes sense --- there is something wrong in the "cleanup code" generated between case statements --- a bogus "release" is generated and that soon causes the EXC_BAD_ACCESS.)

I also discovered this, which might be related: http://openradar.appspot.com/11329693