views:

36

answers:

2

I am a 15 year veteran of C++ and thought I could easily handle the memory issues on the iPhone. But I have been humbled by this new environment at several turns. Here is my problem. I hope I am asking the question correctly.

Basically, I am keeping a mutable array of my common object at the appdelegate. This seems like the reasonable place to maintain a collection of objects that are used by multiple different views. However, between the time I create and push the view to the nav controller and the time the view starts to use those values, the location in memory where I created my objects is getting stomped with different values.

I reviewed all of my code to make sure the reference counts were accurate but did not find anything. So I commented out ALL "release" calls to guarantee the objects still exist but the stomping still continues.

My question is this... Is there something happening that I need to be aware of when I "push" a view that could cause my memory to get stomped? I have a button the user pushes that will alloc-init a viewcontroller and then does a "pushViewController" for the containing nav controller. I verify on the subsequent line that my objects were created and I track the memory. Unfortunately the memory gets stomped as the button event unwinds to a "PurpleEventCallback".

Does this make any sense to anyone? Is there something happening to my view that is not commonly known that causes my memory to become invalid?

+1  A: 

Hey Marcus,

Welcome to SO! It sounds like you're doing everything right. Just to be sure that retain/release is not causing problems, try retaining your array structure again before you push the view controller. Remember that some constructors return objects with a retain count of 1, and others return autoreleased objects with a retain count of zero. As a general rule, all functions beginning with "new", "create" or "alloc" return objects with a +1 retain count. Other convenience functions like [NSMutableArray arrayWithCapacity:] and [NSString stringWithFormat:] return objects that have been autoreleased and have a retain count of zero. If you keep a pointer to these objects, they'll randomly disappear as the run loop cleans things up.

You might also look into debugging using the "zombies" technique. It is very useful when you start randomly getting EXE_BAD_ACCESS errors. Check out this page for more information: http://www.cocoadev.com/index.pl?NSZombieEnabled

From that article: "...with zombies enabled, messages to deallocated objects will no longer behave strangely or crash in difficult-to-understand ways, but will instead log a message and die in a predictable and debugger-breakpointable way. This is the tool to use when trying to track down over-releases and premature releases."

Hope that helps!

Ben Gotow
To be precise: Methods that start with `alloc` or `new` or contain `copy` are the only ones that return non-autoreleased objects.
Nikolai Ruhe
+1 for NSZombieEnabled. As a long-time C++ developer I really needed to read Memory Management Programming Guide for Cocoa with particular attention to ownership.http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
Curt Nichols
Here I thought I was being smart by setting my original array size and creating building the string on the fly. I had no idea they were autoreleased. I went back and found several discrepancies that needed to have their ref-counts bumped. Thanks!Marcus
Marcus Cole
A: 

You might not have read about the concept of auto-release pools in Cocoa before. Autoreleasing an object postpones the release of an object to the end of the current event cylcle (or whenever an autorelease pool is drained).

To check if autoreleasing is your problem, set the environment variable NSEnableAutoreleasePool to "NO". If the problem goes away, autorelease was your problem.

Nikolai Ruhe
Dang it! I thought I had commented out all paths that could decrement my objects to see if that was the issue. After reading both of your replies I went back and found an "autorelease" I had missed. That was another of my problems (additional to previous comment above). We didn't have those in C++ so it is going to take a little getting used to here.Thanks guys!Marcus
Marcus Cole