views:

67

answers:

2

I am programming my first iPhone app (which crashes with an EXC BAD ACCESS error).

I've read a few other similar answers, but still don't have a clear picture of how to fix my code.

Can someone help fix my memory management for the UITableViewCell *cell object in this snippet:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCityCellReuseID];
    if (cell == nil)
    {
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCityCellReuseID];
     cell.selectionStyle = UITableViewCellSelectionStyleBlue;
     cell.textLabel.text = [[self.myData objectAtIndex:indexPath.section] valueForKey:kDisplayText];
     [cell release];
    }
    return cell;
}
+3  A: 

You have to call [cell autorelease] instead of [cell release]. When you release the cell there, it gets deallocated immediately before you can return it to the table view and the table view can take ownership of it (i.e., retain it).

If you autorelease the cell, you signal that you are giving up ownership of the object (which is the right thing to do since you have created it with alloc), but it does not get released until the autorelease pool gets to it. By that time, the table view will have retained the cell.

If you did not autorelease the cell (i.e. if you deleted the release line), your program would not crash, but it would leak memory every time a new cell is created.

Ole Begemann
Release never deletes anything immediately. It simply decrements its retain count.
Azeem.Butt
@NSD: And if the object has a retain count of 1, the object will be deallocated immediately.
Chuck
No it will not. It *might* be deallocated on the next trip through the run loop, but never immediately. This has all been documented very thoroughly for decades now.
Azeem.Butt
Thanks - somehow I got confused that autorelease should not be used in iPhone apps (why?? I dunno) But I was able to go out and confirm what you said by googling and finding another SO answer: http://stackoverflow.com/questions/1219575
Jeff Meatball Yang
Ole Begemann
What NSD is describing appears to be autorelease rather than just plain release. Like he describes, autorelease does indeed depend on the run loop in most applications, and the precise time an object is dealloced with can be hard to predict with autorelease (which is why Apple recommends against overusing it on the RAM-starved iPhone). But release works the way Ole and I said.
Chuck
A: 

Your app crashes because your are returning an object that is already released inside your function. You could instead of releasing it in your function pass the ownership to the caller of the function. Then it's to the caller to release the object when he's done with it.

Mez
You're right that the release is causing the crash, but simply passing the object back to the caller is totally against the Cocoa memory management rules.
Chuck
You're right, although this will work, it should be taken with caution.
Mez