I am attempting to debug an issue where an object is released too many times and is then deallocated by the event loop. The next time I try to read from the object, the application crashes with EXC_BAD_ACCESS.
To debug, I am enabling NSZombies and then using the Zombies profile with Instruments. I then reach the point where my app crashes and Instruments informs me about a message being sent to a deallocated instance. So far, so good.
It does a very good job of showing me where libraries such as UIKit are releasing and retaining the pointer to my object, but it does not show me where my own code is doing this. It is also not displaying the true reference count. By the time that Instruments says that the reference count is 1, the reference count is actually 8 according to printing out the reference count in gdb.
I have investigated the possibility that Instruments is somehow filtering the output but it would appear that I really am recording every release and retain event. It absolutely must be something in my application because my view controller is instantly deallocated after displaying, meaning that attempting to do anything that would send a message to the controller would crash it.
After placing a breakpoint in the dealloc method, I found that my object is indeed being deallocated by the event loop, so this is not a case of a rogue call to dealloc by something else.
You can't rely on reference count as Apple's Framework classes may hold their own references to your objects. The reference count is meaningless for debugging.
Click in the (i) left of the Allocations-Graph
Set "Record reference counts"
You are done ;)
Related
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.
I have a view with some buttons, text fields, and methods. When I load the view, switch to another view, and then switch back, my app crashes. I added in an NSLog in each method to see what the last method call before the crash was, and it was -(void)dealloc{
I am wondering why this method was called? Is it called every time you reload a view? I've double checked my code and I definitely do not call it anywhere.
EDIT : Found my problem, I was releasing an array that I was using to store views. Thanks to #Darren I traced my problem.
Dealloc is called when a class is no longer needed and removed from memory.
When you have no more pointers holding onto anything in the view, then it's dealocated.
How are you switching to/from the view?
if you set a (strong) pointer to the view then it won't be dealocated automatically.
-dealloc is called whenever an object's reference count drops to 0. To find your problem, figure out what object's -dealloc was called. What's the second method on the call stack? The third? Was -dealloc sent to a valid object pointer in the first place?
There are several ways to approach this sort of thing. A good first step is to turn on NSZombies (Google for it). That'll let you know if you're sending a message (like, say, dealloc) to an invalid object. Usually, that causes a crash, but with NSZombies you'll get a nice error message instead.
I enabled the nszombie in xcode 4.2. (from product->editScheme)
I have got this message:
-[buttons respondsToSelector:]: message sent to deallocated instance 0x48ae50
I do have buttons class, but i dont see what the exact problem by this message.
can i get more from the NSZombie ?
The problem is that an object of type buttons was deallocated and then it's respondsToSelector: method was called, that object is at address 0x48ae50.
If you were running without NSZombies your application would have crashed.
What this specific message means is that the buttons instance (at 0x48ae50) has been deallocated (a.k.a. released). So, by trying to send the respondsToSelector: message to nothing (remember the instance has been de-alloc'd), it throws an error.
Try setting a breakpoint near the place where it's being triggered and see why... (for now, your buttons object will most like have an address of 0x0)
In most (if not all) cases, this has to do with some faulty memory management; an object being released too soon, not retained when it had to, etc... ;-)
I have a cocos2d project. Everything works fine, except when I am replacing a scene.
When replacing the scene, I receive the message "Message sent to deallocated instance" followed by a memory address.
The way my project is structured, most CCNodes are children of the main "Scene" which is replaced. These nodes are also stored in various arrays for iterating among similar objects etc.
I can't imagine how I am over-releasing any of the objects, since adding to arrays should increase the reference count, as should adding to the main scene.
Should I do something about this? What happens if I ignore it? (Turn NSZombies off?) The error pops up when objects are being deallocated, so it should just mean that the object is already release right?
Any suggestions on how I can figure out what I am doing wrong?
You need to fix it, as it will cause crashes once you turn NSZombies off. Somewhere in your code your memory management isn't correct. Xcode can help you find it: run Product -> Analyze (Shift-Command-B).
What's a smart method to track class properties history in Xcode ?
I have a zombie property, and I don't understand when it is over released.
Also, I don't want to introduce memory leaks by erroneously over retaining it in the wrong place.
Thanks
I'm not sure what you exactly mean by tracking the history but on overreleasing objects there is an excellent tool called Instruments that can be used in conjunction with the NSZombieEnabled flag. The latter enables tracking that catches access to already-released objects (e.g. when overreleasing you access the release selector one more time on an already released object).
To do this in XCode 4 you select your app, select it to run in the simulator and Choose (in the Menu) Run -> Profile. Now Instruments should launch and present a selection of profiling options. You now select Zombies, the app starts and as soon as you hit a zombie object, a little flag will pop up in the timeline. There (clicking the arrow) you can access the offending object, the object's history (i.e. who retained and released that object) and if you enable the right sidebar, you also get a stacktrace for every entry.