0

I'm working on an iPad app in which I have a table view. When the user selects a row in the table, I use didSelectRowAtIndexPath to open a popover. I'm getting an error message saying "message sent to deallocated instance" when I try to use a certain button. I originally though the errors was getting thrown by the popover (in it's viewDidLoad or something), so I put a breakpoint in and stepped through the code. To my surprise, I was able to step all the way through the loading of the popover and the rest of the didSelectRowAtIndexPath on my table view (which actually just involves stepping out of some if blocks). The error then gets thrown when I get a couple steps into the automatically generated code that doesn't appear in any of my class files (that looks like 0x0010d71d <+1164> mov 0x6...).

So, my question is, how do I find where this error is being thrown? Is there another method that is automatically run after didSelectRowAtIndexPath that could be getting messed up somewhere?

GeneralMike
  • 2,951
  • 3
  • 28
  • 56
  • 1
    Does it tell you which message and which class the instance belongs to? – Phillip Mills Sep 12 '12 at 18:32
  • 1
    are you using `autorelease` when you alloc the popover? – jere Sep 12 '12 at 18:35
  • @Phillip Mills: it's saying -[CFString release]. I never use a CFString explicitly myself, so it must be from something else. Maybe I'll google it and see if I find anything helpful. – GeneralMike Sep 12 '12 at 18:56
  • @jere: I'm using `performSegueWithIdentifier`and `-(void) prepareForSegue` to show my popover, and the controller is a `@property` of my view controller, so I think that means it should be autoreleased, correct? I'm pretty new to working with Macs, so a lot of this stuff is still a bit over my head. Most of what I have is copied from tutorials I've found on SO and youtube, but I don't usually know why it's set up that way, and some of the concepts are still a little fuzzy to me. – GeneralMike Sep 12 '12 at 19:06

2 Answers2

1

Enable NSZombieEnabled in your DEBUG build (see How do I set up NSZombieEnabled in Xcode 4?) to locate instances of objects you're accessing that have been deallocated/released.

Also, consider upgrading your project to ARC, which will likely resolve memory management issues like this.

Community
  • 1
  • 1
CSmith
  • 13,318
  • 3
  • 39
  • 42
  • I have NSZombieEnabled already, and when I do an Analyze the only things I'm getting are a bunch of "value stored during its initialization is never read" on the cells in my popover (which is also built from a UITableViewController). I'm not familiar with this message, so I'm looking it up now, to see if that's something helpful. – GeneralMike Sep 12 '12 at 19:09
  • Edit: it's not on the cells in my popover, it's on the cells in my original view's `cellForRowAtIndexPath`. – GeneralMike Sep 12 '12 at 19:17
  • So right now in my `cellForRowAtIndexPath` I have: `static NSString *CellIdentifier = @"Cell"; MyCell *cell = (MyCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell = [[[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; //plus some stuff about setting labels from an array for indexPath.row` From what I gather, I'm doing an alloc for `cell` twice. This part I pretty much copied straight from a tutorial, so not really sure exactly what it does, or which one I need to get rid of, or how to fix it. – GeneralMike Sep 12 '12 at 19:31
0

Okay, everyone's responses lead me to find malloc error -[CFString release], which helped me figure out I had a string in my popover that I alloc in viewDidLoad by

myString = [NSMutableString stringWithString:[myGlobalFunctionClass getMyString]];

Since I alloc it this way, it gets set to autorelease. The problem was I was explicitly [myString release]; and myString = nil; in viewWillAppear. Removing the release and =nil parts cleaned up my error.

To answer the actual question that I posted, I believe the autorelease wasn't firing until the simulator actually tried to display the popover (which would run after didSelectRowAtIndexPath). Since that occurs after I explicitly [myString release] in viewWillAppear, it was trying to autorelease something that was no longer there. Just to reiterate, the proper way to do it was let it autorelease at the end, and not [myString release] anywhere in my code.

Can someone verify that this is correct? As I mentioned in my comments, I'm still very new to iOS development. I have a feeling at the end of this project, I'm going to be able to go back to first stuff I did in it and make dozens of improvements in terms of doing things more efficiently and more in accordance with best practice.

Community
  • 1
  • 1
GeneralMike
  • 2,951
  • 3
  • 28
  • 56
  • 1
    Yes, [myString release] is a huge no-no on an auto-released object. Upgrade to ARC, there is a WWDC 2011 video on what ARC is an how to update your project. – CSmith Sep 13 '12 at 13:30