ViewController respondsToSelector message sent to deallocated instance CRASH
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In iOS development, a common yet perplexing issue that developers encounter is a crash caused by a message being sent to a deallocated instance, such as a ViewController
. This specific crash often logs an error similar to: ViewController respondsToSelector: message sent to deallocated instance
. Understanding why this crash occurs, its symptoms, and ways to debug it is crucial for building stable applications.
Understanding the Problem
Objective-C and Messaging
Objective-C uses a dynamic runtime system that allows objects to send messages to each other. When you call a method on an object, a message is sent to that object. The method (or selector) will be executed if the object can handle it. If the object is deallocated, the memory reference is invalid, making the instance unavailable for the method call.
Deallocated Instances
When an instance of a class, such as a ViewController
, is deallocated, its memory is freed, and accessing that memory results in undefined behavior. If a message is sent to this deallocated memory, it could lead to a crash because the runtime is trying to execute code on a non-existent object.
When Does This Happen?
This crash typically occurs in scenarios including:
• Delayed Method Calls: When methods are called after a delay using performSelector:withObject:afterDelay:
, and the object has been deallocated within that delay.
• Timers: Objects scheduled on a timer continue to receive tick
or callback messages even if they have been deallocated.
• Notification Centers: Posting notifications to objects that have been deallocated yet are still registered as observers.
• Delegation and Data Source Patterns: If a delegated instance is destroyed without proper cleanup, subsequent delegate messages will cause an error.
Example Scenario
Consider a simple scenario where a ViewController
issues a delayed method call that survives the screen transition and eventual deallocation of the ViewController
.
• (void)viewDidLoad { • (void)testMethod {

