NSAutoreleasePool drain releases +1 more than the number of sent autorelease messages - objective-c

I've been having trouble debugging an iPhone app that crashes in a reproducible way.
Short story:
A custom UIViewController is allocated and pushed onto a UINavigationController's stack.
Some time later the UIViewController is poped from the stack.
The very next push of a UIViewController onto the stack crashes the app.
The standard procedure for any crash is using the Instruments with NSZombie enabled.
Upon inspection of the object's history some is revealed that I fail to understand:
the object receives 2 (two) autorelease messages and
the NSAutoreleasePool's drain method send 3 (three) release messages
So far, the only way to prevent crashes is to NOT send 1 (one) release message to the object in question and thus raising a red flag for memory leaks, only that it doesn't leak.
Is there any other solution that I've overlooked?
Update: As one of you pointed out the obvious:
You have a problem in your code. Nothing to do with autorelease pool drain.
It turned out that the first UIViewController was passed as a delegate to the UINavigationController hence my confusion when the Zombie call was coming from the navigation controller itself.
I should me more careful next time before asking the wrong question.

Related

An Objective-C message was sent to a deallocated object (zombie) at address: 0x75d52a0

I am relatively new to iOS development so appreciate your help in finding out the root cause for the error that I encountered.
I tried to debug the error using Instruments (i.e. Allocations-Zombie Profiler) but I could not make sense of the call stacks that were presented.
This is how the user interfaces are linked:
TabBarController -> NavigationController -> TopPlacesTableViewController -> RecentPhotosTableViewController -> PhotoViewController
The error occurs when I click on the Back button in the last view (i.e. that of the PhotoViewController). This action is supposed to show the previous RecentPhotosTableViewController but instead an unknown deallocated object was accessed, sometime in between the events of viewWillAppear and ViewDidAppear.
Additionally, I have a GenericTableViewController which is the parent of TopPlacesTableViewController and RecentPhotosTableViewController. The children set a NSMutableArray property in the parent which is the data that gets loaded in the children's views.
I am currently using iOS6 and XCode4.5.
[Update: In the Console, this line was shown - "[UIView _forgetDependentConstraint:]: message sent to deallocated instance xxx"].
I feel you are not using ARC, and you are not retaining of passing your previous object. In the meantime the previous object is released and then you accessing it.
Either you can refactor your code to use ARC or put retain or autorelease.
Go to Product > edit scheme >Diagnostics tap then check on enable Zombie objects
make a break point and go step by step to know which object is deallocated, it perhaps the pointer to your object has been removed then the OS has deallocated your object.

ARC: Memory does not get reclaimed?

I am working on an iPad (only) app and I stumbled across a weird problem. The app gets terminated after a memory warning on iPad 1 but works fine on iPad 2.
I am using ARC and targeting iOS 5. I use nibs and most of my assets are displayed using UIImageViews. I also have a few hundred buttons and plenty of gesture recognizers... I re-watched the WWDC11 videos (sessions 323 and 322) on ARC and I don't seem to be doing anything special.
The app is UIImage intensive, I am doing lots of animations using UIImage. I am however using the initWithContentsOfFile constructor rather than the imageNamed call. I'm trying to prevent the images from being cached by the system.
I'm also using GCD to schedule sound effects and to animate views. I'm always doing this on the main thread.
The app uses a UINavigationController that never has more than 1 UIViewController on it's stack. I can confirm that this is true because the didReceiveMemoryWarning only gets called on the current view controller (I'm logging the call).
The thing I don't understand is why Instruments is reporting high numbers (as if the view controllers don't get deallocated) in both the Allocations and VM Tracker instruments. The Allocations instrument shows a small drop when I navigate from one view controller to another (which is what I expect) but the VM Tracker Instrument shows that the Dirty Size is not dropping when I do the same thing. Eventually the app uses too much memory and gets terminated (on iPad 1). When I get memory warnings on the iPad 2 the app does NOT get terminated though...
It feels as if my images, sounds or views don't get destroyed and the memory does not get reclaimed... My object hierarchy is very basic and there should not be any retain cycles of any sort. I don't even have simple delegates...
Do you have any suggestions? I really don't want to release this app only for the iPad 2 or newer... It's an app for kids and it would be a pitty... I'd be so much happier to learn that I'm doing something wrong, as I really want to make sure this app is the best it can be...
Cheers,
Nick
There are ways to say, 'optimise' your objects by setting their properties to nil when certain things aren't needed -- so while you can't write a dealloc method anymore, you can do self.object = nil (when pertinent) which ends up doing something like this in a non-ARC world for an 'retain' (i.e., strong) property:
- (void)setObject:(id)newObject
{
[object release]; // send release message to current object
object = newObject; // set reference to newObject
[object retain]; // send retain message to newObject
}
Now while in ARC you don't/can't write retain/release yourself in your code, the compiler inserts these calls for you, meaning that in practise, setting a property to nil would do this in the above example:
[object release]; // send release message to current object
object = nil; // set reference to nil
[object retain]; // send retain message to nil (no effect)
Moreover, this is just the tip of the iceberg -- you should make sure that there are no retain cycles in your code, which could be resulting in objects leaking without recourse to their destruction. This means, that there may be places where you're using strong references to a property (i.e., an object), when you should be using a weak property. The difference being, that strong references are retained, and weak references are assigned, the former having its retainCount incremented and the latter resulting in a property assignment that looks like this if handwritten:
- (void)setObject:(id)newObject
{
object = newObject;
}
I don't like answering my own question but I figured it could be helpful to future googlers. I implemented my own UIImage based animation and I no longer use the animationImages property. Turns out my memory issues are now gone as I no longer need to store all the images in memory and I load them as they are required using a timer.
I actually think that rolling out a custom animation is beneficial since it allows for callbacks and more powerful customisation options.
Once I'm happy with it and I feel like it's ready to be shared I will post the class(es) on GitHub.

iOS (iPad) CoreGraphics & Foundation memory issues

I'm getting strange memory allocations from core iOS libraries, seen in Instruments Allocations (Malloc 1.00KB) which continually rise and result in app crash (iPad).
The app allows the user to browse through articles (body in webview, title/author/date in labels) - the problem occurring as each new view controller is loaded (previous view controllers are released/deallocating - this isn't the problem).
The following CoreGraphics allocations only happen when the .text property is set for the UILabel:
CoreGraphics "CGGLyphBitmapCreate", "CGFontSetStrikeValue" - sometimes one or both of these shows 6 or 7 times (1KB each) but at least one of each every time view loads.
In addition to this, Foundation "[NSNotificationCenter addObserver:selector:name:object:]" sometimes appears, sometimes not, sometimes up to 6/7 times on one load. I understand why adding observes this might allocate some memory, but surely deallocating view controller with "[NSNotificationCenter removeObserver:self] should remove all references again.
I've included screenshots from Instruments... won't even address the WebCore and libcache.dylib allocations that **sometimes show up on load. Very confused here too.
Did you track leaks? As long as it doesn't leak memory you normally don't have to worry.
Maybe you have a thread without an autorelease pool set up? If this is the case, and an autorelease object is created, e.g. by a getter method, the object cannot be retained by an autorelease pool since it does not exist, and it will leak.
So it your app is multithreaded, make sure that every thread has an #autoreleasepool{} block that covers most of the thread code.

memory too high in UINavigationController

i've a navigation controller with several viewController and tableViewController.
I'm using all autorelease objects, the problem is that when i push a new view and i use it, memory from Instrumets increase of a bigger value of memory released when i come back in the navigationController. There's not leak warning, when i return to the view then, memory will not increase again, it's like if was all in cache.
I've tried also using objects own by me, with alloc....and release but the story is the same. Is it normal?
UIViewControllers (or to be exact, views/resources/xibs associated with them) are interesting since iOS will hold on to the resources in memory and unload them as required. This is why often the dealloc method will seem like it's never called. However don't worry, if you did proper memory management, your controllers and resources will be freed up as required - if there's a low memory warning sent to your app, all the views that are hidden or have been popped, will be unloaded and dealloc'ed.
Try testing your app again, just like you did before, but this time emulate low memory usage (can be done in simulator from the Hardware menu), then see if memory usage drops due to your controllers being freed up by the system

"message sent to deallocated instance 0xec75b0", but 0xec75b0 shouldn't even be visible

I'm working on an iPhone app that performs some communication with the server to be initialized the first time it's run. I have a class ServerCommunication with methods for each of the basic tasks to be performed (authenticate user, get activation key, download updates, etc.), and a new instance of ServerCommunication is created for each task; I'm not reusing them, although it would be more efficient.
When the user completes the first initialization screen, ServerCommunication gets created four times. I keep track of it with NSLog(#"Initializing ServerCommunication instance %p", self); in its -init method. The second initialization screen also calls ServerCommunication a few times when the user taps the "Next" button, but on its last instantiation, the app hangs with the message -[ServerCommunication insertDataIntoLocalDB:]: message sent to deallocated instance 0xec75b0 in the console. The thing is, 0xec75b0 is the address of the first instance of ServerCommunication I created way back at the first screen.
Why would it be sending messages to that instance? I'm not retaining them anywhere; they're mostly autoreleased. If it helps, all of the methods in that class perform asynchronous downloading of XML data with NSURLConnection and then parse it with NSXMLParser. The parser's delegate method -(void)parserDidEndDocument:(NSXMLParser *)parser then sends off NSNotifications that are received by methods in my view controllers so they know whether to proceed to the next screen or stay there and display an error message.
Help is much appreciated!
The first thing I would do is turn on NSZombies, which should let you break at the point where your zombie is being messaged.
A common cause of problems like this is when you have objects with weak references to each other that are not allocated and deallocated at the same time. So (hypothetically), some other object stores a pointer to your ServerCommunication object as a delegate or owner. When ServerCommunication is deallocated, it doesn't unregister, and then some time down the road the object holding the weak reference tries to message you.
If I had to completely guess (and I do!) I bet you add your ServerCommunication objects as an NSNotification observer, but never remove them. Try making sure that you do this:
[[NSNotificationCenter defaultCenter] removeObserver:self];
sometime before deallocation. (It's also possible that there's a more circuitous path involving NSNotification here -- such as a pointer to the ServerCommunication object being passed as data to the view controller, which is then trying to message it.)