iPhone Sdk: [MobileOfferViewController _shouldUseKeyWindowStack] - iphone

I have a memory leak, so i tried to debug with nszombie....
And NSZombie printed this:
-[MobileOfferViewController _shouldUseKeyWindowStack]: message sent to deallocated instance 0x6307580
So my question: what is the method: shouldUseKeyWindowStack??
Found nothing on Google....
Thanks,
Martin

I fought with a similar error for quite some time. Best I can tell, _shouldUseKeyWindowStack is an internal UIResponder method that showed up in iOS 4.0 (I assume related to multitasking somehow).
However, the real error with this type of thing is usually a memory access error (too many releases on an object, or a threading error). In my case, it was a threading error - specifically, trying to update the UI (show a UIAlert) in a background thread. I ended up wrapping the code that was causing the crash in it's own method and then calling [self performSelectorOnMainThread:withObject:waitUntilDone:] to work around the crash.

Related

Tracking down EXC_BAD_ACCESS without NSZombie?

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.

Memory management error, using cocos2d for iPhone

So I'm getting a EXC_BAD_ACCESS error in cocos2d. From what I've been searching so far it's mostly related to attempting to free an object which has already been released. I have encountered this error before, and its solution was simple and pretty much caused by freeing a released object. But now, using cocos2d (not sure if it's a bug in their framework or not), I'm getting an EXC_BAD_ACCESS in this line:
CCMenuItemSprite *btn = [CCMenuItemSprite itemFromNormalSprite:op selectedSprite:op target:self selector:NSSelectorFromString([sceneMethods objectAtIndex:i])];
Basically, I'm creating a simple menu system for easy maintenance and updating. Nothing too serious. In this particular line, I'm creating a CCMenuItemSprite with self as target and using a selector. I've already asserted that the selector passed as argument is correct and also tried to use different for the normal and selected sprite (though that shouldn't make any difference) but still no go! The error is deep in the cocos2d framework, precisely when the CCMenuItem is "activated" which calls invoke on a NSInvoker of that same class. And analyzing the stack trace, it crashes exactly on the invoke method, which leads to believe it has something to do with the NSInvoker. Anyone had a similar problem or have a suggestion for this problem? Thanks in advance.
Just a guess: are you completely sure that all of the objects in sceneMethods are real selectors?

Help debugging iPhone app - EXC_BAD_ACCESS

I've developed my application using my 3G device to test with. Upon giving this to a friend to test, he's noticed that it crashes..I've had a look at the crash log, but it's not much use except for the "EXC_BAD_ACCESS" statement after a few memory warnings.
On my device, I can use the imagePicker lots, and each time a photo is taken I get a memory warning, but this doesn't cause any problems.
On my friend's device (also a 3G), after a couple of images chosen from the camera, the app crashes.
So, my question is.. I think something is being deallocated because of the memory warning - but only on my friend's device, and then after deallocation, it's trying to be used again. How can I find out what object is being called? I can't use NSZombies because this is a remote (beta) device.
Help please!
Also if anyone has any ideas why my device can pick image after image without any problem and his can't...that would be most helpful
Thanks!
EDIT: New discovery.. I'm getting this error message too: KERN_PROTECTION_FAILURE which I understand to be something to do with data access. The crash seems to happen right after I save the image got from the UIImagePicker. Any ideas?
You may be over-releasing something. If you're running Snow Leopard, run the Static Analyzer (Cmd-Shift-A) and look for memory errors.
The fact that it crashes after a memory error suggests that a UIViewController has released its view. Do you have any UIViewControllers that observe NSNotifications, or otherwise might change their IBOutlets while they are off-screen? This is a common cause of this kind of crash. Make sure you're correctly memory managing your IBOutlets. UIViewControllers should never mess with their IBOutlets (or their UI components at all) when they are off screen. Even if you don't make this mistake, if you're not implementing things as noted in the above link, you can still crash after memory warnings.
MemoryWarning was a pretty good idea, and things have improved, but Apple still hasn't quite cooked all the issues around how it plays with UIViewController. The developer still needs to be very careful.
You should have your friend come to your computer and run it with NSZombieEnabled. That's the best way to debug these issues.

iphone debugging help- see when objects are released?

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

TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION error iPhone SDK development

I have a working program that was written by another programer that I am trying to add some features to in an effort to learn the iPhone SDK. I have carried out what I would assume was a fairly simple task of adding an additional UIButton to an existing view with like buttons. I have used the other UIButtons as a model and it seems this should be a simple task.
The problem is when the line that calls this subview is executed I get the rather vague error flag of TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION. Where do I find more information on this error code? I looks to me like a very general error and certianly there must be someplace in the Xcode shell that gives me more detail on what this means?
I have isolated the line where it occurs and it seems to happen on the first reference to the new view. Is it a problem with the connections made in interface builder? Any suggestions would be helpful as I really feel like I am grasping at straws at this point...
You want want to trap the exception when it happens, you might then be able to track it down in the debugger. A useful set of breakpoints to use when your debugging Cocoa apps are objc_exception_throw and -[NSException raise]. In the iPhone I think all exceptions travel through objc_exception_throw but if your were targetting Tiger or earlier you should set a breakpoint on both.
There are more debugging techniques at http://www.cocoadev.com/index.pl?DebuggingTechniques.
This is an exception generated by the Objective-C runtime. Hit CMD-SHIFT-R to bring up the debugger console. You'll see all the gdb startup information at the bottom of the window, but if you scroll up past the stack info, you'll get to something that should look like this:
[Session started at 2009-04-09 14:39:27 -0700.]
2009-04-09 14:39:31.246 LearnGLES[10415:20b] *** -[EAGLContext fakeMessage]: unrecognized selector sent to instance 0x528150
2009-04-09 14:39:31.248 LearnGLES[10415:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[EAGLContext fakeMessage]: unrecognized selector sent to instance 0x528150'
2009-04-09 14:39:31.250 LearnGLES[10415:20b] Stack: (
2517758219,
2486509115,
....
That's just a complete sample exception that I made up by changing code to send a non-existent message to an object, but there are a lot of possibilities as to what yours might be. Anything that would generate a run-time exception in any of the Objective-C frameworks could be the culprit (un-parseable dates to a date formatter, invalid messages to objects, etc...)
It probably means that you used some memory after deallocating it or used it without initializing it. Often when you look at the stack after this all you'll see is the part of the main loop that performs the autoreleases, which clearly isn't going to help you.
Really you need to get a good understanding of how memory management works in Objective-C and then take a look at your changes. There's not really a silver bullet here. The good news is that it gets easier with experience.
This is a nice article about debugging in Objective-C.
What connections have you made in interface builder? Are you making a call to any methods when the button is clicked? What is the method signature in that case? Have you made any changes to the original code, where you might have accidentally deleted some code which was important. It would help if you post some code. The exception is very generic.
I had a similar problem when I released things that I had not explicitly allocated.
In my case, I had a background image UIImage *image=[UIImage ...] and was setting it to be the background of my UIButton, and then did [image release];
You don't want to do the [image release]: the UIButton owns it now, and it will free it when no longer needed.
Maybe you have a similar issue?