Recibir un warning cuando envias un mensaje con @selector() y no está implementado

Autor: | Última modificación: 30 de mayo de 2023 | Tiempo de Lectura: 1 minutos
Temas en este post:

Nunca más una excepción de Unrecognized Selector sent to instance

En el curso de fundamentos de programación iPhone que imparto en @agbotraining, al tercer día vemos las notificaciones.  Llegados a este punto, son muchos los alumnos que se estampan contra el mismo problema: la aplicación se les cae con una excepción del tipo:

SigABRT

terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[PenViewController fooBarBaz]: unrecognized selector sent to instance 0x811db50’

¿Suena familiar? Eso es porque después de pedir que se envíe un mensaje mediante @selector:
  • no implementan dicho mensaje
  • o, si lo implementan, lo hacen con otro nombre (lo típico es olvidarse de los dos puntos o cambiar una minúscula por una mayúscula o vice versa).

Más de uno se encabrona con el compilador por no avisar y me toca volver a explicar que Objective C parte del principio que sabes lo que estás haciendo y que si envías un mensaje que aparentemente no está implementado, tus razones tendrás. 😉

Sin embargo, sí que hay una forma de asegurarse de que el compilador te de un warning cuando vea que envía sun mensaje con @selector() y éste no está implementado.

Aviso cuando un mensaje en un @selector() no está implementado: -Wundeclared-selector al rescate

Aquí vemos que envío un mensaje con performSelector: que no está implementado en mi clase, y el compilador me está dando un warning:

warning cuando envias un mensaje

-Wundeclared-selector

Para conseguir esto, tenemos que usar la opción de compilación -Wundeclared-selector. Siempre y cuando no vayas a hacer virguerías en tiempo de ejecución con forwardInvocation: & cia, es perfectamente seguro y hasta recomendable cuando estás depurando.

Para activarla, basta con ir al proyecto y a los build settings:

Wundeclared-selector
Uso de Wundeclared-selector