简体   繁体   中英

Iphone app crashes with EXC_BAD_ACCESS error in iOS 4.3 but works fine on previous versions

I have created an app which is approved by apple and currently buyable in the appstore. But after the 4.3 update it crashes when scrolling the UITableView with the EXC_BAD_ACCESS error. NSZombieEnabled = YES, will get the app working again but this isn't a solution of course ;) The error is reported in the Main class on the following line:

int retVal = UIApplicationMain(argc, argv, nil, nil);

Also the stacktrace doesn't help me out either:

> #0  0x00faf09f in objc_msgSend ()
> #1  0x04c7b9e0 in ?? ()
> #2  0x00d6004c in CFRelease ()
> #3  0x00e42369 in -[__NSArrayM removeObjectAtIndex:] ()
> #4  0x00e3dcfc in -[NSMutableArray removeObjectsInRange:] ()
> #5  0x003507a5 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] ()
> #6  0x0034890c in -[UITableView layoutSubviews] ()
> #7  0x01d80a5a in -[CALayer layoutSublayers] ()
> #8  0x01d82ddc in CALayerLayoutIfNeeded ()
> #9  0x01d280b4 in CA::Context::commit_transaction ()
> #10 0x01d29294 in CA::Transaction::commit ()
> #11 0x01d2946d in CA::Transaction::observer_callback ()
> #12 0x00e2a89b in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
> ()
> #13 0x00dbf6e7 in __CFRunLoopDoObservers ()
> #14 0x00d87857 in CFRunLoopRunSpecific ()
> #15 0x00d87761 in CFRunLoopRunInMode ()
> #16 0x017371c4 in GSEventRunModal ()
> #17 0x01737289 in GSEventRun ()
> #18 0x002dec93 in UIApplicationMain ()
> #19 0x000026d4 in main (argc=1, argv=0xbffff068) at
> /Users/geoffrey/Documents/iPhone
> projecten/Xcode Projecten/HU
> Rooster/main.m:14

Can someone please help me out with this? I'm trying to get this working for 2 days now :(

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

    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = customCell;
        self.customCell = nil;
    }
    int num = indexPath.row;

    if (indexPath.section != 0) {
        for (int i=1; i <= indexPath.section; i++) {
            num = (num + [[sectorSize objectAtIndex:(i-1)] intValue]);
        }
    }
    // Configure the cell...
        cell.tijdLabel.text = [NSString stringWithFormat:@"%@ - %@", [tijdBeginList objectAtIndex:num], [tijdEindList objectAtIndex:num]];
        cell.lesVormLabel.text = [lesVormList objectAtIndex:num];
        cell.docentLabel.text = [docentList objectAtIndex:num];
        cell.lokaalLabel.text = [lokaalList objectAtIndex:num];
        cell.opmerkingLabel.text = [opmerkingList objectAtIndex:num];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

Check the dealloc method of your Custom Cell implementation and make sure [super dealloc] is the last instruction. I had a similar issue and it turned out I had it calling [super dealloc] before it was releasing some view labels and other items.

These lines

> #3  0x00e42369 in -[__NSArrayM removeObjectAtIndex:] ()
> #4  0x00e3dcfc in -[NSMutableArray removeObjectsInRange:] ()
> #5  0x003507a5 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] (

Give me a hunch that the problem is in the cells you are creating at cellForRowAtIndexPath selector. Something might end up being over released.

Something is being over released and from the look of the stack trace it seems to be a UITableViewCell that is being released one too many times.

You say that NSZombieEnabled = YES keeps it running, which actually surprises me. What NSZombie does, at least when I've been using it, is that it tells you what deallocated object was sent what message, but the application still crashes.

To further help you it would be helpful if you could provide the output from NSZombie as well as your implementation of:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

EDIT: I've never used the interface builder, but I found a line that I found suspicious:

self.customCell = nil;

If the customCell property is a retain property, that line will release the custom cell. Try changing that property to an assign property.

The difference might be that

[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

used to retain the custom cell in previous versions, but doesn't in 4.3. You should figure it out, so that you're not leaking in older versions. Drop a comment if you need more help.

EDIT 2: Ok, so I have one more idea.

You could check the retain count of the cell:

NSLog(@"Retain count: %i", [cell retainCount]);

You could check the retain count in different places and compare it between 4.3 and prior versions. Maybe that way you could figure out what have changed.

I also read the documentation for loadNibNamed:owner:options: and found the following that might be relevant:

(To establish outlet connections, this method uses the setValue:forKey: method, which may cause the object in the outlet to be retained automatically.)

The documentation says that the object may be retained, so I guess that's a behavior that might change between versions.

Your mistake is that you are assigning the cell pointer to the customCell pointer, then setting the customCell to nil, meaning cell will be pointing to a non-valid object.

Use cell = [[customCell copy] autorelease]; instead and you should be good to go.

First, you are reading the stack trace backwards. The crash is in [__NSArrayM removeObjectAtIndex:] (or just below).

Secondly, the problem indicates an object was created, put into an array, and then released to the point of deallocation while the array still held onto it. This is an all too common over-release problem.

Here:

    [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = customCell;
    self.customCell = nil;

You grab a reference to the customCell and then promptly release it. The only reason why it likely sticks around is because NIB loading probably retained/autoreleased the object on load.

Rog's suggestion of retain/autoreleasing the cell is a good one.

But there is a bigger problem; you are loading a nib in the middle of trying to draw a table view .

Loading a NIB is a relatively glacially slow operation to be doing in the middle of something as performance sensitive as drawing a table. It is quite likely that your app's scrolling and/or user interaction is going to be "clunky" because of this.

While cell = [[customCell retain] autorelease]; might fix the crash, I would suggest that you also refactor the code to not do something so expensive during table rendering.

I was getting same issue ...

in cellForRowAtIndexPath:(NSIndexPath *)indexPath

Check your CellIdentifier with CellIdentifier of xib file ...

make your CellIdentifier = @"CustomCell"

This will fix your issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM