Fixing "Unrecognized Selector Sent To Instance" Error In Xcode

Fixing "Unrecognized Selector Sent To Instance" Error In Xcode

One of the most common errors in Xcode is “Unrecognized Selector Sent To Instance“. Today I will try to explain the reason why we get this error and most importantly how to fix it.

But before we start investigating the code, we should better understand the error message in the console area. The Selector might be a new thing for many iOS developers, so first let’s find out what it means.


Selectors in Objective-C

Even though we are currently working on a Swift code we still might see Selector during the runtime. The reason for that is that UIKit was originally coded in Objective-C. Here we are going to take a look at how the things work behind the scenes and in particular how introspection works in Objective-C.

If you haven’t heard of introspection before, the idea is that it allows you to get more information about the classes and methods. The following data can be extremely helpful during the debugging. And as you might have guessed already Objective-C has the full support for introspection.

The selector is an internal ID for a method, but we don’t have to worry about the ID itself. The only thing which is important right now is that we use selectors to access the ID for a method. The reason why the internal ID is not important is that it might change with the new OS release.

So to get a selector we either use the @selector keyword and then give the name of the method, which will return the ID.

SEL aSelector = @selector(methodName); 

Another alternative is to get it from a string using the function NSSelectorFromString and the name of the methods.

SEL aSelector = NSSelectorFromString(@”methodName”);

Unrecognized Selector Error In Xcode

Here I will include some code to demonstrate the possible case scenario when we get the following error. As we can see here I have an IBOutlet which is called imageView. So this Outlet is connected to a UIImageView element in my storyboard.

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var imageView: UIImageView!
    

    override func viewDidLoad() {
        super.viewDidLoad()
        self.imageView.image = UIImage(named: "myImage")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

Here I’m referencing that imageView has an image property and I’m setting that image property to a new UIImage object, with a random name of an image called myImage.

self.imageView.image = UIImage(named: “myImage”)

So what I’m trying to do here with this line of code is to set the image of the imageView, so that I can display some sort of output when I run the app.

Understanding Error Message


Once you run this line of code you will instantly get an error message in the console area, which looks like this (unrecognized selector sent to instance). Since the selector is another name for the method, the error is basically saying that it doesn’t recognize the function that you’re trying to call on this object.

[UIButton setImage:]: unrecognized selector sent to instance

The error also gives us the information that we are trying to call the set image method of an object that is a UIButton. Well, that’s really strange because our property is a type of UIImageView and I know for a fact that UIImageView has a method called set image. Or in other words, when you set the image property it’s actually calling the set image method. 

Well, this error message says that you’re trying to call set image method on a button. Maybe the element that is connected to this property even though we think it’s a UIImageView is not?! This actually happens quite a lot because in the storyboard you may have elements overlapping each other.

So while connecting your IBOutlets you might have accidentally highlighted the button and connected it to the Swift code, while thinking it was image view. That’s why the error message is referencing that the button is connected to the imageView property of this view controller.

The Takeaway: Invoking a method that doesn’t exist will crush your application.

Fixing the Error


The simple yet effective solution to this problem is to right click on the UIButton and break the connection. Now inside the viewController.swift the grey dot will be empty in a circle meaning that this property is no longer connected to the outlet.

Once everything is cleaned up it’s time to make a new connection and the circle will be highlighted in solid gray if everything is done the right way. Now your app won’t crash because it’s going to call set image method on a UIImageView element which is what we expected.

Final Thoughts

Next time if you see an error message: “unrecognized selector sent to instance”, start debugging by investigating objects with the type ID. It’s possible that the class of the offending object is not what you think it is at runtime. Therefore try to use introspection to check if the object responds to the selector in question.

I hope this article was helpful and has saved you time in debugging.