I'm a little ways into developing my first iphone app, and I've been running into exc_bad_access a lot. (I'm sure it's because I'm not designing stuff in a very MVC-proper way yet.)
It's extremely frustrating trying to hunt down why I'm running into these errors all the time... is there a way in the xcode debugger to keep a watch list of pointers, so you can actually see when various objects are being released? Something, anything that can give me more of a visual understanding of why my program design is flawed?
In particular, I keep having trouble with my "webobject" class I've wrapped all of my NSURLConnection methods in. When I try to call performselector to the view controller that initiated a "webobject" request, I keep getting exc_bad_access when I try to access the webobject's synthesized properties. Is there something fundamentally wrong with my notion that I should wrap all of my webservice-related methods into a class that I can import anywhere?
Dave,
I don't know of a way to trace the deallocation of objects (especially native objects like NSStrings). But, I experienced a similar abundance of exc_bad_access messages when starting Objective-C programming. But one day I read something that helped me alot to get rid of these messages:
If you create an object using alloc, copy, or a method that begins with new, then it is your object to manage and dealloc. You can call retain and release and that cycle will work as expected on those objects. If you never call release or dealloc on it, it will hang around foreever and be a leak. If you call a method that is something like 'stringWithFormat', numberWithYadaYada then that object is set for autorelease. Meaning, as soon as you exit the method that is using it, it may get dealloced. Therefore, if you've called one of these autorelease methods, you must retain it if you want to see it later on.
I suspect that either your delegate or NSURLConnection is getting autoreleased, that is the cause of your bad access messages.
Jack
You could try creating a breakpoint on -[NSObject dealloc] (or the same method on the subclass you are targetting).
I would also refer you to one of the many Cocoa memory handling tutorials.
I ended up reading up about NSZombieEnabled, which has helped me track down those exc_bad_access messages. More info here: http://www.cocoadev.com/index.pl?NSZombieEnabled
Just as a general thing, you should run as a static analyzer and it will probably tell you when you are over or under retaining objects.
pertinent stackoverflow question
Related
I've run into an issue with zombie/overreleased objects (in this case a CFArray). The problem is that I can't figure out where it's coming from. I'm doing a whole bunch of NSURLConnections at once, and according to Instruments, all the calls that lead to the overreleasing of the object are made in CFNetwork.
I'm kind of new to Instruments. Is there a way I can trace the call stack for these memory events? It might help me find where I'm going wrong.
Enable NSZombie flag in edit scheme.It will let u know where exactly ur app is crashing.And make sure disable it once u figure out the crash.because it will not release all released objects wihch will lead to huge memory usage.
I'm building an application that reads rss files something like Bing or Pulse, so I've built a class (UIViewController) that shows each individual entry in the feed and a class that contains that list of entries and another class that shows all the feeds at once, and I've not used any xib files so I've implemented a method in each class that gets called after each rotation to reset the frames of the views inside that class. But I'm facing a problem in the memory especially when calling that method when a rotation happens knowing that it just assigns a CGRect to each frame in the view.
So could you please help me to avoid this problem or suggest a different way to avoid it, and am I right about not using xib files or should I use them when ever I can and set the rotation thing inside them (using the auto resizing mask).
And if there is some complex free example like those applications, could any body point me to it.
Any help would be greatly appreciated,
and thanks in advance...
First, there is no reason to avoid nib files when they are useful to you. They are often useful. There is no reason to use nib files when they are not useful to you. If you have complex layout, they are definitely very useful. Whether to use them or not, however, is a personal choice based on the particular application. As a beginner, I would recommend using them and getting comfortable with them, and particularly relying on the Xcode templates to set them up correctly.
Nib files aren't your issue, one way or another here. You're leaking memory, and you need to investigate why. First, run the static analyzer to make sure there are no obvious errors. Then run your app under Instruments (Leaks) and look for large leaks. Then run your app under Instruments (Allocations) and look for what's eating the most memory. That should point you to your error.
The most likely cause, without any insight into your code, is that you are misusing ivars. Make sure that you access your ivars through accessors (except in init, dealloc and in the accessors). Directly accessing your ivars is the #1 cause of memory problems in iOS.
Release the objects properly which has been allocated and defined globally. Do not release the object of your UIViewController when it is active. Most of the leakage problems occur by releasing the object of the UIViewController before it reaches out of scope.
I am trying to access the UITextView delegates and have a problem
I have a UIViewController with the UITextViewDelegate protocol and a Nib containing the textView.
If I set the delegate inside viewDidLoad like "textView.delegate = self" and I touch the textView, the app crashes without logging errors.
If I start editing the textView with code like "[textView becomeFirstResponder]" all delegates get called.
When I set the delegate in the Nib creating a connection between the textView and the File's owner and deleting "textView.delegate = self" also no delegates get called.
What am I doing wrong here?
Regards,
Elias
It's not easy to help you without more description, posted code or a xib file.
You say application crashes without any logging errors - well, do you mean that there's no output in console's window ? That is normal, for an app that has crashed.
Anyway, you should be able to get the stack-trace to figure out where approximately the application has crashed. Open the debugger (⇧⌘Y), and see the position. That should give you an idea of what went wrong.
Here you can see an example of such debugger session (after EXC_BAD_CRASH):
First two lines doesn't give us much information, but later on we can see that application has crashed while loading user interface from a NIB file. Well, usually the only code that executes during such load are awakeFromNib methods - it's up to you to find a problem along those lines.
Often top of code's execution doesn't make any sense - for example you might see your ViewController method somewhere, but the top few function calls (those where the code crashed) are located in methods/classes which you never call in your code. In most cases that is a sign of wrong memory de-/allocation. What might happened is that you forgot to retain some of your objects, it has already been released, but you are still keeping reference (a pointer) to its memory. Because that memory has been in fact freed, another object took its place later on, usually some Apple's internal object you've never heard about. Later on your code tries to message your poor object but it sends a message to something completely different. BUMMER! That's how you get those crashes and strange stack traces.
To fix the kind of problem I've just described you can use Instruments and its Zombies instrument. Unfortunately you can't start Zombies from within Xcode, you need to start Instruments standalone, then choose the Zombies under iPhone Simulator/Memory, then Choose Target from the toolbar, you should see your application in there, or be able to navigate to it on filesystem.
What Zombies instrument does is that it never really frees memory after objects are deallocated. Instead, it will mutate those objects into NSZombie class. That class intercepts all calls to itself, and informs you when some code is trying to send a message to it.
This is how such Instruments session looks like (this is the same crash as seen in debugger above):
In the table you can see that we're trying to message UIScrollView that has already been deallocated. You can as well see the whole history of retain/release calls to this particular object. That way you can find a missing retain or wrong release/autorelease.
Remember - Zombies Instruments can only be used with Simulator, because there's not enough memory on the real device to keep all those memory blocks.
Hopefully I could help you with further analysis of your problem.
I've spent two days on this and I still can't find the cause of the crash.
I know it has something to do with trying to access an object that has been freed but I don't know which access or which object.
Whenever I google trying to find the source of EXC_BAD_ACCESS people suggest using NSZombies. The problem is when I enable zombies (either in xcode via environment variable or in instruments via ObjectAlloc properties) the program doesn't crash where it usually does and the zombies don't report anything (nothing shows up in logs and nothing is flagged in instruments). Is there something I'm missing with NSZombie?
I've tried utilizing some information from xcode's debugger and from ObjectAlloc in instruments but all the information is very cryptic and doesn't really help me.
I've set the debugger to stop on objective-c exceptions. When it does it this is the call stack shown:
0 objc_msgSend
1 ??
2 -[UITableViewCell removeFromSuperView]
3 -[UIView dealloc]
... etc ...
First of all, what's the deal with '1 ??' ? What do the question marks mean? Second of all how can I know where this was called in my code? All the operations stated are too generic (eg UIView dealloc, but which UIView? And where?).
Also when the exception occurs it points to assembly code which again, doesn't do me any good unless I was to spend hours trying to figure out what the code does. I know some assembly but there has to be a better way... right?
Is there any way I can get meaningful information as to what was the last line that ran in my code before the exception occurred?
I've tried sprinkling some NSLogs and breakpoints around but it doesn't help me much because the crash happens after I pop a view controller from a navigation controller. Everywhere I place breakpoints the breakpoints are reached fine (I can't find a point to break after the crash). It's only when I 'continue' in the debugger that the exception occurs. It's as if the crash happens outside of my code so I have no idea where to get a handle on it.
I've looked through my code and double checked that I adhere to all the memory management rules (at least to the best of my knowledge). I'm sure it's something very subtle but I can't seem to find it.
If anyone has any ideas how to find such bugs without NSZombie please share.
Thanks.
Well I found the problem. I had a custom table cell class in which I called [super dealloc] first in the dealloc method (rather than last). I guess I wrote this class in a hurry and didn't really think about it. I'm guessing something got released in the parent that the child needed for releasing?
So I don't have a real answer to my own question but basically I found the problem using a combination of ad-hoc code tracing and various debugging techniques (breakpoints, NSLogs, trying to decypher cryptic stack trace,etc).
Actually the main strategy that helped me was commenting out code bit by bit until I stripped down the problem area into as simple as it gets while still keeping the crash intact. This let me realize the problem wasn't where I thought it would be but in a more subtle area (eg in the dealloc method of a secondary class in this case).
I hope this can sort of help someone out. I'll leave this question unanswered for a bit incase someone has a more thorough debugging strategy without relying on NSZombies. Also if someone can clarify what those two question marks mean in the stack trace that would be helpful.
I'm trying to use XCode's Leaks utility to fix some memory leaks in my code. Is there a better and more understandable way to check for leaks with explanations that pinpoint the exact line and/or offer suggestions?
Another question, I'm using AVAudioRecorder in my code in one of my view controllers. Should I load the recorder in viewDidLoad or in viewWillAppear?
If you're using Snow Leopard, have you tried using the static analyzer?
As mentioned, use Static Analyzer as a first line of defense.
It will not find everything.
But here's the problem with what you are requesting of Leaks. Think about what a leak is - a leak is when you have memory, that should have been released, but it is not.
So that means you are MISSING a line of code, that could have been placed anywhere - doing the actual release at the right time. But how could the tool possibly know when something SHOULD have been released?
So instead, the tool does the next best thing. It tells you where the leaking memory was allocated, then from there it's up to you to figure out where the object travelled and when it should actually have been released.
Static Analyzer will find the cases where you should have released in a few lines of code from when you created the object. Anything else, you just need to use Leaks to get a starting point to track down when you need to release something elsewhere.