objective c - Error "Selector no reconocido enviado a la instancia" en Objective-C
unrecognized-selector (30)
Conceptos básicos: Invocación dinámica
El objetivo C es un lenguaje dinámico que invoca métodos al observar el tiempo de ejecución de los métodos en las clases. Por ejemplo, si hay Clase A que incluye el método DoSomething (arg1, arg2) . Si intentas llamar al método usando argumentos correctos en un objeto de Clase A, todo funcionará bien. Sin embargo, si los argumentos no se transmiten correctamente, por ejemplo, llamó al método con un solo argumento, entonces el tiempo de ejecución tratará esto como una llamada a método para un método diferente. Eventualmente, el tiempo de ejecución no podrá encontrar el método (DoSomething con un argumento) y, a través de esta excepción, "selector no reconocido enviado a la instancia" .
Solución
Compruebe qué firma se espera de @selector . Usualmente lo es, como describiste en el código
-(IBAction)numberButtonClick:(id)sender{
Creé un botón y agregué una acción para él, pero tan pronto como lo invoqué, obtuve este error:
-[NSCFDictionary numberButtonClick:]: unrecognized selector sent to instance
0x3d03ac0 2010-03-16 22:23:58.811
Money[8056:207] *** Terminating app
due to uncaught exception
''NSInvalidArgumentException'', reason:''*** -[NSCFDictionary numberButtonClick:]: unrecognized selector sent to instance 0x3d03ac0''
Este es mi código:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
UIButton *numberButton = [UIButton buttonWithType:UIButtonTypeCustom];
numberButton.frame = CGRectMake(10, 435, 46, 38);
[numberButton setImage:[UIImage imageNamed:@"one.png"] forState:UIControlStateNormal];
[numberButton addTarget:self action:@selector(numberButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview: numberButton];
}
return self;
}
-(IBAction)numberButtonClick:(id)sender{
NSLog(@"---");
}
..Y ahora mio
Tuve el botón vinculado a un método que accedió al parámetro de otro botón y funcionó bien, PERO tan pronto intenté hacer algo con el botón en sí, tuve un bloqueo. Durante la compilación, no se ha mostrado ningún error. ¿Solución?
No logré vincular el botón al propietario del archivo. Entonces, si alguien aquí es tan estúpido como yo, intente esto :)
Actualmente estoy aprendiendo el desarrollo de iOS y revisando el libro "Beginning iOS6 Development" por aPress. Obtuve el mismo error en el Capítulo 10: Guiones gráficos.
Me llevó dos días resolverlo, pero descubrí que accidentalmente configuré la etiqueta de la celda TableView en 1 cuando no debería haberlo hecho. Para cualquier persona que haga este libro y reciba un error similar, espero que esto ayude.
¡Realmente espero que los errores futuros en mi código sean más fáciles de encontrar! jajaja. El error de depuración no hizo nada para empujarme en la dirección correcta para resolverlo (o al menos soy demasiado nuevo para entender el depurador, lol).
Creo que deberías usar el vacío, en lugar de IBAction en el tipo de devolución. porque definiste un botón programáticamente.
En mi caso, estaba usando NSNotificationCenter y estaba intentando usar un selector que no tomaba ningún argumento, sino que estaba agregando dos puntos. Eliminar el colon solucionó el problema.
Al usar un nombre de selector, no use un punto de partida si no hay argumentos. Si hay un argumento, use un punto final. Si hay más de un argumento, debe nombrarlos junto con un punto posterior para cada argumento.
Vea la respuesta de Adam Rosenfield aquí: Selectores en el Objetivo C
En mi caso, la función no esperaba un argumento, pero el botón estaba configurado para enviar uno que causaba el error. Para arreglar esto tuve que volver a conectar el controlador de eventos.
Aquí está mi función:
Observe que no contiene argumentos.
Aquí hay una imagen de la configuración de mi botón (haga clic derecho en el botón para verla):
Tenga en cuenta que hay 3 controladores de eventos.
Para solucionar esto, tuve que eliminar cada uno de los elementos del evento, ya que uno de ellos se enviaba una referencia a sí mismo a la función enterPressed. Para eliminar estos elementos, hice clic en el pequeño icono x al lado del nombre de cada elemento hasta que no se mostraron los elementos.
Luego tuve que volver a conectar el botón al evento. Para hacer esto, mantenga presionada la tecla Control y luego arrastre una línea desde el botón hasta la acción. Debería decir "Conectar acción". Nota: tuve que reiniciar XCode para que esto funcione por alguna razón; de lo contrario, solo me permite insertar acciones (también crear una nueva acción) arriba o debajo de la función.
Ahora debe tener un único controlador de eventos conectado al evento de botón que no pasa argumentos:
Esta respuesta complementa la respuesta de @Leonard Challis, que también debe leer.
En mi caso, yo estaba usando un UIWebView y pasé un NSString en el segundo parámetro en lugar de un NSURL. Así que sospecho que los tipos de clases incorrectos pasados a funciones pueden causar este error.
Esta fue la principal respuesta de Google para este problema, pero tuve una causa / resultado diferente: pensé que agregaría mis dos centavos en caso de que otros tropezaran con este problema.
Tuve un problema similar esta mañana. Descubrí que si hace clic con el botón derecho en el elemento de la IU que le indica el problema, puede ver qué conexiones se han creado. En mi caso, tenía un botón cableado para dos acciones. Eliminé las acciones del menú contextual y las volví a configurar y mi problema se solucionó.
Así que asegúrate de que tus acciones estén conectadas correctamente.
Esto me pasó a mí porque borré accidentalmente la "función @IBAction ..." dentro de mi código de clase UIViewcontroller, entonces en el Storyboard se creó el Outlet de referencia, pero en el tiempo de ejecución había alguna función para procesarlo.
La solución fue eliminar la referencia de salida dentro del inspector de propiedades y luego volver a crearla arrastrando con la tecla de comando al código de clase.
¡Espero eso ayude!
Esto también puede suceder cuando desea establecer una propiedad desde un ControllerA a una propiedad pública dentro de una clase personalizada de ControllerB y aún no ha establecido la "Clase personalizada" dentro del inspector de identidad en los guiones gráficos.
Esto también puede suceder si no configura la "Clase" de la vista en el constructor de interfaz.
Estoy respondiendo a Leonard Challis, ya que también estaba tomando la clase de Stanford iOS C193P, al igual que el usuario "oli206"
"Aplicación de finalización debido a excepción no detectada ''NSInvalidArgumentException'', razón:"
El problema era que tenía el botón "Entrar" en la calculadora conectado dos veces, y un amigo señaló que al hacer una inspección del botón en el guión gráfico se mostraba que había 2 entradas en los atributos "Retocar adentro" cuando hice clic derecho en el botón "Entrar". Al borrar uno de los dos "Eventos enviados" "Retocar adentro" se solucionó el problema.
Esto mostró que el problema se desencadenó (para la clase de video C193P en la Calculadora Tutorial en la Tarea 1) como 2 eventos enviados, uno de los cuales estaba causando la excepción.
Incluyendo mi parte. Me quedé atrapado en esto por un tiempo, hasta que me di cuenta de que había creado un proyecto con ARC (referencia de conteo automático) deshabilitado. Un conjunto rápido de SÍ en esa opción resolvió mi problema.
La causa más obvia de esto (incluida para completar) es lanzar incorrectamente un puntero y llamar a un método de la clase incorrecta.
NSArray* array = [[NSArray alloc] init];
[(NSDictionary*)array objectForKey: key]; // array is not a dictionary, hence exception
Me sucedió debido a conflictos de argumentos conflictivos.
Mi problema y mi solución fueron diferentes y pensé que debería publicarlo aquí para que los futuros lectores puedan evitar que su cabeza se golpee contra la pared.
Estaba asignando diferentes xib al mismo UIVIewController e incluso después de buscar en todas partes no pude encontrar cómo corregirlo. Luego revisé mi AppDelegate donde estaba llamando a initWithNibName
y puedo ver que al copiar el código, cambié el nombre xib, pero olvidé cambiar la clase UIViewController
. Entonces, si ninguna solución le funciona, verifique su método initWithNibName
.
OK, tengo que entrar aquí. El OP creó dinámicamente el botón . Tuve un problema similar y la respuesta (después de horas de cacería) es tan simple que me enfermó.
Cuando usas:
action:@selector(xxxButtonClick:)
or (as in my case)
action:NSSelectorFromString([[NSString alloc] initWithFormat:@"%@BtnTui:", name.lowercaseString])
Si coloca dos puntos al final de la cadena, pasará el remitente. Si no coloca los dos puntos al final de la cadena, no lo hará, y el receptor recibirá un error si espera uno. Es fácil omitir los dos puntos si está creando dinámicamente el nombre del evento.
Las opciones de código del receptor se ven así:
- (void)doneBtnTui:(id)sender {
NSLog(@"Done Button - with sender");
}
or
- (void)doneBtnTui {
NSLog(@"Done Button - no sender");
}
Como de costumbre, siempre es la respuesta obvia la que se pierde.
Otra causa realmente tonta es tener el selector definido en la interfaz (.h) pero no en la implementación (.m) (pe typo)
Otra posible solución: agrega ''-ObjC'' a tus argumentos del enlazador.
La explicación completa está aquí: categorías Objective-C en la biblioteca estática
Creo que la esencia es: si la categoría está definida en una biblioteca con la que estás enlazando estáticamente, el enlazador no es lo suficientemente inteligente como para vincular los métodos de la categoría. La bandera de arriba hace que el enlace del enlazador esté en todas las categorías y categorías del objetivo C, no solo en las que cree que necesita al analizar su fuente. (Por favor, siéntete libre de sintonizar o corregir esa respuesta. Conozco los idiomas enlazados, así que estoy repitiendo el loro aquí).
Otra solución / caso ligeramente diferente.
Estoy usando Xamarin y MvvmCross y estaba intentando vincular el UIButton a un ViewModel. Tuve el UIButton conectado a un Outlet y un TouchUpInside.
Cuando Enlace, solo uso el Outlet:
set.Bind (somethingOutlet).For ("TouchUpInside").To(vm => vm.Something);
Todo lo que tuve que hacer fue eliminar la conexión de acción (TouchUpInside) en XCode y eso lo resolvió.
PD. Supongo que esto está en su base, todo relacionado con las respuestas anteriores y con @Chris Kaminski en particular, pero espero que esto ayude a alguien ...
Aclamaciones.
Otro motivo / solución para agregar a la lista. Este es causado por iOS6.0 (y / o mala programación). En versiones anteriores, el selector coincidiría si los tipos de parámetros coincidían, pero en iOS 6.0 obtuve bloqueos en el código que funcionaba anteriormente donde el nombre del parámetro no era correcto.
Estaba haciendo algo como
[objectName methodName:@"somestring" lat:latValue lng:lngValue];
pero en la definición (tanto .h como .m) tuve
(viod) methodName:(NSString *) latitude:(double)latitude longitude:(double)longitude;
Esto funcionó bien en iOS5 pero no en 6, incluso la misma versión exacta implementada en diferentes dispositivos.
No entiendo por qué el compilador no pudo decirme esto, de todos modos, problema con la suela.
Para aquellos que llegan aquí a través de Google como yo lo hice, lo que probablemente se relaciona más con Xcode 4.2 + / iOS 5+ más, con ARC. Tuve el mismo error " selector no reconocido enviado a instancia ". En mi caso, tuve una acción de destino de UIButton configurada para pasarla como el parámetro del remitente, pero luego me di cuenta de que no la necesitaba y la eliminé en el código. Entonces, algo como:
- (IBAction)buttonPressed:(UIButton *)sender {
Fue cambiado a:
- (IBAction)buttonPressed {
Al hacer clic con el botón derecho en el UIButton en cuestión, se mostró que el evento Touch Up Inside estaba asociado con el método viewViews buttonPressed: method. Quitar esto y reasignarlo al método modificado funcionó.
Para mí, fue una conexión sobrante creada en interfacebuilder bij ctrl-dragging. El nombre de la conexión interrumpida estaba en el registro de errores
*** Terminating app due to uncaught exception ''NSInvalidArgumentException'',
reason: ''-[NameOfYourApp.NameOfYourClass nameOfCorruptConnection:]:
unrecognized selector sent to instance 0x7f97a48bb000''
Tuve una acción vinculada a un botón. Presionando el botón se colgó la aplicación porque el Outlet ya no existía en mi código. La búsqueda del nombre en el registro me llevó a él en el guión gráfico. ¡Lo eliminó y el accidente ya no está!
Parece que no se está administrando correctamente la memoria del controlador de visualización y se está desasignando en algún momento, lo que hace que el método numberButtonClicked:
se envíe a otro objeto que ahora ocupa la memoria que el controlador de vista estaba ocupando anteriormente ...
Asegúrate de estar reteniendo / soltando apropiadamente tu controlador de visualización.
Puede suceder cuando no se asigna ViewController a ViewControllerScene en InterfaceBuilder. Entonces, ViewController.m no está conectado a ninguna escena.
También tuve el mismo problema.
Eliminé mi uibutton en mi guión gráfico y lo recreé ... ahora todo funciona bien.
Tuve el mismo error y descubrí lo siguiente:
Cuando usas el código
[self.refreshControl addTarget:self action:@selector(yourRefreshMethod:) forControlEvents:UIControlEventValueChanged];
Puede pensar que está buscando el selector:
- (void)yourRefreshMethod{
(your code here)
}
Pero en realidad está buscando el selector:
- (void)yourRefreshMethod:(id)sender{
(your code here)
}
Ese selector no existe, así que obtienes el colapso.
Puede cambiar el selector para recibir el remitente (id) para resolver el error.
Pero, ¿qué sucede si tiene otras funciones que llaman a la función de actualización sin proporcionar un remitente? Necesitas una función que funcione para ambos. La solución fácil es agregar otra función:
- (void)yourRefreshMethodWithSender:(id)sender{
[self yourRefreshMethod];
}
Y luego modifique el código desplegable de actualización para llamar a ese selector:
[self.refreshControl addTarget:self action:@selector(yourRefreshMethodWithSender:) forControlEvents:UIControlEventValueChanged];
También estoy haciendo el curso Stanford iOS en una Mac anterior que no se puede actualizar a la versión más nueva de Mac OSX. Así que sigo construyendo para iOS 6.1, y esto me solucionó el problema.
Tuve el mismo problema. El problema para mí fue que un botón tenía dos métodos de acción. Lo que hice fue crear un primer método de acción para mi botón y luego eliminarlo en el controlador de vista, pero olvidé desconectar la conexión en el guión gráfico principal en el inspector de conexiones. Entonces cuando agregué un segundo método de acción, ahora había dos métodos de acción para un botón, lo que causó el error.
Tuve este problema con un proyecto de Swift donde estoy creando los botones dinámicamente. Código de problema:
var trashBarButtonItem: UIBarButtonItem {
return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked")
}
func newButtonClicked(barButtonItem: UIBarButtonItem) {
NSLog("A bar button item on the default toolbar was clicked: /(barButtonItem).")
}
La solución fue agregar un colon completo '':'' después de la acción: por ej.
var trashBarButtonItem: UIBarButtonItem {
return UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "newButtonClicked:")
}
func newButtonClicked(barButtonItem: UIBarButtonItem) {
NSLog("A bar button item on the default toolbar was clicked: /(barButtonItem).")
}
Ejemplo completo aquí: https://developer.apple.com/library/content/samplecode/UICatalog/Listings/Swift_UIKitCatalog_DefaultToolbarViewController_swift.html
Tuve un problema similar, pero para mí la solución fue ligeramente diferente. En mi caso, utilicé una Categoría para extender una clase existente (UIImage para algunas capacidades de cambio de tamaño - vea este modo en caso de que esté interesado) y olvidé agregar el archivo * .m al objetivo de compilación. Estúpido error, pero no siempre es obvio cuando sucede dónde mirar. Pensé que valía la pena compartir ...