2011-02-10 30 views
12

Simplemente comenzando con el desarrollo de iPhone y Objective-C.Cuándo usar dos puntos con un @selector

Ayer estaba tratando de addObserver de una notificación en una vista de la mía, y me quedé conseguir este error:

unrecognized selector sent to instance

que lo rastreó al hecho de que tenía que incluir los dos puntos de fuga a mi argumento de selección:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nameOfMySelector:) name:@"BBLocationServicesAreDisabled" object:nil];

Hoy en día, pensé que era inteligente, porque la hora de establecer el argumento acción a un botón, recordé mi error de ayer, y añadí los dos puntos para el argumento de la acción. El argumento de acción toma un @selector, al igual que el argumento selector mientras se configura un observador para una NSNotificación, así que pensé que estaba haciendo lo correcto.

Sin embargo, con el siguiente código:

[self.callToActionButton addTarget:self action:@selector(nameOfMySelector:) forControlEvents:UIControlEventTouchUpInside];

me sale exactamente el mismo error:

unrecognized selector sent to instance

Lo que da? ¿Por qué un @selector requiere un punto final y el otro no? ¿Cuáles son las reglas que debo seguir para cuándo debe incluirse y cuándo debe dejarse, y por qué no puedo siempre hacer solo una u otra?

Gracias!

+1

Es un punto, no un punto y coma. De todos modos, ¿cuál es el prototipo de su método 'nameOfMySelector:'? ¿Qué tipo de argumento quiere? – BoltClock

+0

¿También se refiere al mismo método en ambos casos? – BoltClock

+0

¡Ja! Un descuido de mi parte; He editado la publicación para referirme a ellos como dos puntos. – djibouti33

Respuesta

29

Según lo mencionado por boltClock, el personaje que usted se refiere es en realidad un colon. La diferencia entre @selector(method) y @selector(method:) es la firma del método. La segunda variante espera que se pase un parámetro.

@selector(method) esperaría que el método: -(void)method

@selector(method:) esperaría que el método: -(void)method:(id)someParameter

+3

Ahí vamos, eso es exactamente. Tiene sentido total Gracias por la respuesta rápida y por la lección de gramática :) – djibouti33

8

Parece que le falta un concepto aquí: colon es, de alguna manera, una parte del nombre del método. Por ejemplo, método

-(IBAction) doIt:(id)sender; 

tiene el nombre doIt:. Por lo tanto, los dos puntos deben usarse para hacer referencia a este método.
Pero este método no tiene una coma al final

-(IBAction) doItWithoutParameter; 

Lo mismo sucede con los métodos de aceptar varios argumentos, que tienen nombres como doItWithParam1:andParam2:

2

El colon indica que el método toma un parámetro.

[someObject performSelector:@selector(doSomething:)] significa que doSomething está esperando un parámetro.

[someObject performSelector:@selector(doSomething)] significa que doSomething no necesita ningún parámetro.

2

En su caso:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nameOfMySelector:) name:@"BBLocationServicesAreDisabled" object:nil]; 

- (void) nameOfMySelector: (NSNotification *) notification { 
    /* this method would require the semi-colon */ 
} 

o en este caso:

[self.callToActionButton addTarget:self action:@selector(nameOfMySelector:) forControlEvents:UIControlEventTouchUpInside]; 

- (void) nameOfMySelector: (id) sender { 
    /* this method would also require the semi-colon */ 
} 
5

Un selector representa un nombre de método, y el número de dos puntos en un selector coincide con el número de argumentos en el método correspondiente:

  1. mySelector - sin dos puntos, sin argumentos, por ejemplo - (void)mySelector;, [self mySelector];
  2. mySelectorWithFoo: - un punto, un solo argumento, p. Ej. - (void)mySelectorWithFoo:(Foo *)foo;, [self mySelectorWithFoo:someFoo];
  3. mySelectorWithFoo:withBar: - dos puntos, dos argumentos, p. Ej. - (void)mySelectorWithFoo:(Foo *)foo bar:(Bar *)bar;, [self mySelectorWithFoo:someFoo bar:someBar];

y así sucesivamente.

También es posible tener un selector sin 'nombrar' los parámetros. No es recomendable, ya que no está claro de inmediato lo que los parámetros son:

  1. mySelector:: - dos puntos dobles, dos argumentos, por ejemplo, - (void)mySelector:(Foo *)foo :(Bar *)bar;, [self mySelector:someFoo :someBar];
  2. mySelector::: - tres puntos, tres argumentos, p. Ej. - (void)mySelector:(int)x :(int)y :(int)z;, [self mySelector:2 :3 :5];
Cuestiones relacionadas