"unrecognized selector sent to instance" in release mode and not in debug mode - objective-c

I have an app which generate a lot of "unrecognized selector sent to instance" errors in Release mode an non in Debug.
Do you have any idea on where can be the issue?
Thanks and regards,

Are you releasing for the same SDK (10.6, 10.5...) as your debug mode? You might be calling a method that only exists in 10.6. This should produce a warning, however. Are you taking care of warnings rather than ignoring them?

If you release an object before you're done using it, and another object gets allocated at the same address, sending a message intended for the old object will hit the new object, and if they're of different classes, you'll get that exception.
Run the static analyzer (or, better yet, turn it on to run on every build in your build settings). The static analyzer will show you the simpler bugs of this nature—the “low-hanging fruit”.
Then, run your application under Instruments's Zombies instrument. If you still have a bug of this kind (but too sophisticated for the static analyzer to spot), the Zombies instrument will put a flag in the timeline when you send a message to a should-be-dead object. You can then begin hunting down the bug from there. Repeat until there are no more crashes.

It probably occurs because you are linking a framework in one mode and not the other, make sure when you add frameworks you are linking that you are in "All Configurations".

Related

ERROR objc_retainedObject() unavailable

when i'm trying to build my project I have a new error where objc_retainedObject() is used.
I have the error message objc_retianedObject is unavailable: use CFBridgingRelease() or a (__bridge_transfer id) cast instead.
I replaced the usages of objc_retainedObject() by CFBridgingRelease and there are no longer errors and I can run the app, but when the app is going to display my QRCode-scanning view, it crashed without messages.
It is the same when I put #define objc_retainedObject(o) ((__bridge_transfer id)(objc_objectptr_t)(o)) which was supposed to be a solution.
I believe that it is an XCode configuration or a missing library problem. Any ideas?
Do not recreate objc_retainedObject. It was removed on purpose. CFBridgingRelease and CFBridgingRetain are the correct tools for moving CF objects into ARC. (__bridge is the tool for dealing with CF objects that you don't need to transfer to ARC because you aren't storing them.)
If your program is crashing, you're probably managing memory incorrectly. It is likely that objc_retainedObject was incorrect (even if you happened to get away with it). See when should you use __bridge vs. CFBridgingRelease/CFBridgingRetain? for correct memory management when transferring CF objects to ARC.
Without knowing more about the code, I can't guess exactly where you've made a mistake, but you probably are calling CFBridgingRelease on an object that you didn't acquire via the Create Rule. You don't just throw CFBridgingRelease on every CF object you encounter. You need to make sure you're balancing an existing retain.

Objective-c static analysis tool

My crash reporting service is showing a large number of mystery crashes for an iOS app. For a few reasons I suspect the code is trying to perform a selector on an object that doesn't have the particular selector.
How can I statically analyze the code to find the erronous selector?
I'm writing Objective-C code using Xcode 4.6 on OS X 10.8. I'm ok with a tool that doesn't pick up things like calling performSelector where the selector is built from a string etc. I think a basic tool will work.
Select "Analyze" from the "Product" menu in Xcode. Or press shift+command+B.
It's invaluable for identifying routine memory management stuff in MRC. But it's still useful for ARC programs.
You might also want to try setting an exception breakpoint for all exceptions.
I'd also refer you to the Debug and Tune Your App section of the Xcode User Guide. Or Ray Wenderlich's My App Crashed, Now What? series.
By the way, while the analyzer helps, I don't think it will find incorrect selectors. You might want to share how you're using selectors, because it you're using performSelector, there are often better patterns. Sometimes you have to use it, but frequently there are other patterns that are more robust. Or if you absolutely need to use selectors, add runtime respondsToSelector checks. For example:
NSAssert([object respondsToSelector:#selector(someMethod:)], #"%# does not respond to selector someMethod:", object);
Or, conditionally perform the selector if it responds to it (this is how you perform a method that might be conditional on a particular iOS version):
if ([object respondsToSelector:#selector(someMethod:)])
[object performSelector:#selector(someMethod:)];

How do I debug weird memory management issues in Xcode/Objective-C?

I'm newish to Objective-C and my memory management skills are not great. However, I haven't had a single problem until now. And now I've got big problems.
I've gone from zero crashes to crashing at random points, giving me either no console output or unrecognized selector errors on random types (-[NSCFSet isSameAsStop:]: unrecognized selector - I don't even use any sets and I surely have not called my custom isSameAsStop on any sets.). Judging by the randomness and errors, it seems like a memory thing to me although I'm not entirely sure.
How do I go about debugging this? The debugger assumes you know where your problem is... and mine is just everywhere. Ideas?
SOLUTION COMMENT
Some clarification on the solution suggestion to "run with zombie detection enabled":
Set the NSZombieEnabled to YES on the Executables' Arguments screen.
Build and then choose Run with Performance Tool > Object Allocations, which will start Instruments.
Click the "i" button on Object Allocations in Instr. and select zombie detection and retain counts.
Rerun and click around in your app, it'll tell you when you hit a zombie!
Thanks for the help!
You have a classic over-release bug on your hands. Somewhere, you are over-releasing an instance of the class that implements isSameAsStop and it just so happens that an NSSet instance is allocated at the same spot after the original instance is deallocated.
The first step is to "build and analyze" your code, fixing any problems that the static analyzer finds.
The next step is to then run with zombie detection enabled.
In Xcode: Build menu >> Build and Analyze
Finds a lot of common memory management issues.

Watching messages to an object in Xcode debugger

I'd like to use gdb or Xcode's debugger to watch every message sent to an object in an Objective-C 2.0 program. I don't care about arguments and such, as I just need to see every message it receives (retain, release, autorelease, etc). I also don't want to profile my entire program.
Is there a means, in Xcode, to select an instance (possibly by address) and say "show me every message sent to this object"? Since the plumbing is fairly standard, I imagine there would have to be a probe hook or something. Anyone ever done this?
(Aside from subclassing the object in question, of course; looking for a more general solution.)
This is for iPhone development with Xcode 3.2 on Snow Leopard.
You can set the NSObjCMessageLoggingEnabled environment variable to YES and then grep/filter through the resulting log for the object you're interested in.
Here's a relevant blog post as well, though I'm not sure how much of the information there is still true in the runtime today. (It might all be. I really don't know.)

App crashes without Garbage Collection enabled

As the title says, my app crashes when garbage collection is not enabled. The app pops up for a few seconds and then it just crashes, with nothing but this in the debugger console:
[Session started at 2009-08-17 15:03:20 -0600.]
GNU gdb 6.3.50-20050815 (Apple version gdb-966) (Tue Mar 10 02:43:13 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".sharedlibrary apply-load-rules all
Attaching to process 12535.
unable to read unknown load command 0x22
unable to read unknown load command 0x22
unable to read unknown load command 0x22
unable to read unknown load command 0x22
I don't know why its happening. I think its probably a memory management issue. I used AnalysisTool (front-end to Clang Static Analyzer) to check for leaks and memory management issues, and I fixed the issues it found. Running the app through Instruments however reveals a memory leak around the time it starts. I have no idea where this leak is coming from...With garbage collection enabled the app runs fine, but Instruments still finds a leak.
Source code is available upon request
Thanks
Since the error says it occurs when calling [CFArray countByEnumeratingWithState:objects:count:] on a deallocated object, that gives you a fairly good idea of where to look. That method is part of part of NSFastEnumeration, so unless you're calling that method directly (highly unlikely), it is being invoked from within a for (... in ...) loop on your array object. If you can figure out where that is, you can set a breakpoint on (or just before) the for loop and check whether your object has been deallocated. The most likely cause of the problem is failing to properly retain the array, and it is probably released by the run loop draining an NSAutoReleasePool.
XCode has a bunch of memory profiling support built in - turning those on might reveal more information. I found these links particularly helpful:
http://developer.apple.com/technotes/tn2004/tn2124.html#SECMALLOC
http://www.cocoadev.com/index.pl?NSZombieEnabled
http://www.cocoadev.com/index.pl?DebuggingTechniques
http://www.cocoadev.com/index.pl?DebuggingAutorelease
You're probably releasing an object when you shouldn't, then sending it a subsequent message. unfortunately, the crash (where the subsequent message is sent) isn't where the problem is - it's where you are releasing (or worse, deallocing) where you shouldn't. The clang static analyser isn't foolproof, and blindingly following the advice won't necessarily have helped.
If it crashes after showing something for a few seconds, it may indicate that something that needed to be retained was released by the autorelease pool at the end of the run loop. Have a look at places where you assign variables with objects returned by other methods. Any method without "new", "copy", "alloc" (there's a few others I think) in the name usually indicates that you'll need to retain it if you want to keep using it.
It could also mean that you have released something that you shouldn't have and it was released again by the autorelease pool. Have a look at all the places you are releasing objects and make sure that you are only releasing objects that you have either retained yourself, or releasing objects returned by methods that explicitly state ownership, such as "new", "alloc", "copy", "mutableCopy" and so on.