How can I debug 'unrecognized selector sent to instance' error
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
unrecognized selector sent to instance means the Objective-C runtime tried to send a message to an object that does not implement that selector. In plain terms, your code or Interface Builder asked an object to run a method it does not have, so the app crashed at runtime.
What the Error Really Means
Objective-C uses dynamic message dispatch. A call such as:
is resolved at runtime. If object does not respond to doSomething, the runtime eventually raises an exception like:
The important clues are:
- the actual runtime class name
- the selector name
- the object address
Those three details usually tell you where to look first.
First Step: Read the Exception Literally
If the crash says:
then either:
- the object is not the class you think it is
- the selector name is wrong
- the method signature does not match what was connected or called
Do not start by guessing. Start by checking the exact class and exact selector from the exception message.
Common Cause: Wrong Object Type
A very common cause is storing one object in a variable typed as a broader class and then calling a selector that only exists on some other subclass.
Because id disables compile-time checking, Objective-C will let the call compile and defer the failure until runtime.
A fast debugging trick is to log the real class:
That often exposes a mistaken cast or a wrong object flowing through the code.
Common Cause: IBAction or IBOutlet Mismatch
Another classic source is an old Interface Builder connection. For example, you rename or delete an action method in code, but the storyboard or nib still points to the old selector.
Example:
If the storyboard is still wired to saveButtonTapped: instead of saveTapped:, tapping the button can trigger the crash.
When the error happens after touching a button, loading a view, or interacting with a table view cell, inspect your storyboard connections immediately.
Common Cause: Deallocated Object and Zombies
Sometimes the problem is not really a missing method. It is that the object was deallocated, memory got reused, and now the message is being sent to garbage or to a different object that does not support the selector.
This is where Zombies help. In Xcode, enable Zombie Objects for the scheme. That keeps deallocated objects around long enough to tell you what object used to live there, which makes over-release and lifetime bugs much easier to find.
This is especially valuable in legacy Objective-C code or when bridging with manual memory-management patterns.
Common Cause: Swift and @objc Selector Issues
If Swift code is involved, selectors still matter for target-action, timers, notifications, and other Objective-C runtime features.
For example:
If the method is not exposed correctly to the Objective-C runtime, selector-based APIs may fail. In mixed Swift and Objective-C projects, always verify that the selector signature matches exactly.
Practical Debugging Flow
A reliable debugging sequence is:
- read the class and selector from the exception
- set an exception breakpoint in Xcode
- inspect the object's real runtime type
- check storyboards, nibs, target-action wiring, and notifications
- enable Zombies if memory lifetime looks suspicious
An exception breakpoint is especially useful because it stops at the crash site instead of only showing the final stack trace after the app terminates.
Defensive Checks
In rare dynamic cases, you can guard before sending a selector:
This is useful for plugin-style or reflective code, but it should not be your normal fix for broken architecture. Most of the time you want to understand why the wrong object received the message in the first place.
Common Pitfalls
The biggest mistake is focusing only on the selector name and ignoring the runtime class in the exception. The class often tells you the real bug immediately.
Another common mistake is forgetting stale storyboard connections after renaming actions or outlets. Interface Builder wiring causes a large share of these crashes.
Developers also miss memory issues. If the object should support the selector but apparently does not, a zombie or over-release bug may be disguising the real problem.
Finally, do not silence the error with respondsToSelector: everywhere. That can hide a wiring or type bug instead of fixing it.
Summary
- The error means a message was sent to an object that does not implement that selector.
- Read the exception carefully: the class and selector names are the main clues.
- Check for wrong runtime types, stale storyboard connections, and selector signature mismatches.
- Enable an exception breakpoint and Zombies when the crash is hard to trace.
- Use
respondsToSelector:only for genuinely dynamic code, not as a blanket workaround.
Related reading
- How can I deploy an iPhone application from Xcode to a real iPhone device?
- How can I detect the touch event of an UIImageView?
- How can I detect when an Android application is running in the emulator?
- How can I determine if my React Native app is a debug or release build from JavaScript code?
- How can I delete a RabbitMq exchange?
- How can I delete a topic from DCOS Kafka?
- How can I develop for iPhone using a Windows development machine?
- How can I develop for iPhone using a Windows development machine?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.