2012-01-13 14 views
14

La herramienta de migración ARC se niega a aceptar este código antes de comenzar con la migración:Cómo resolver "ningún método de instancia conocido para el selector 'performSelector: withObject: afterDelay:'" al migrar a ARC?

[self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0]; 

El delegado se ve obligado a poner en práctica este método con un protocolo, y que debería funcionar bien:

@protocol OverlayDelegate <NSObject> 
- (void)overlayDismissed:(Overlay*)overlay; 
@end 

@interface Overlay : UIImageView { 
    id<OverlayDelegate> delegate; 
} 

@property (nonatomic, assign) id<OverlayDelegate> delegate; 

¿Qué pasa con ARC? ¿Por qué me está diciendo que no hay ningún método de instancia conocido para el selector 'performSelector: withObject: afterDelay:'?

Respuesta

16

ARC no está causando esto, simplemente está exponiéndolo. Ese método está definido en NSObject, pero Identificación funciona para algo más que NSObject (lo que tiene que ser más específico que acaba de 'id') Cambiar el código para esto:.

@interface Overlay : UIImageView { 
    NSObject<OverlayDelegate> *delegate; 
} 

@property (nonatomic, assign) NSObject<OverlayDelegate> *delegate; 
+0

¿Eso significa que en virtud de ARC los días en que declaramos que los delegados se han ido? ¿Simplemente confía en NSObject en su lugar? (para mí, eso tiene sentido de todos modos) – openfrog

+1

ARC aplica estas cosas para fines de gestión de la memoria. Si sabe que su delegado será del tipo NSObject, simplemente dígalo y este problema desaparecerá. – dtuckernet

+0

O todavía use 'id' y simplemente no use métodos de' NSObject'. ¿Por qué estás usando métodos de 'NSObject' de todos modos? ¿Hay un requerimiento aquí? – mattjgalloway

0

he descubierto que el delegado de fundición a NSObject * soluciona el problema :

[self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0]; 

Por alguna extraña razón la autocompletación ni siquiera apareció w ith -performSelector:withObject:afterDelay:, así que tuve que escribirlo manualmente. En su lugar, se ofrece sólo -performSelector: y -performSelector:withObject:withObject:

Mi conjetura es que es simplemente estúpido utilizar ID que el tipo para los delegados en Objective-C, y nunca realmente sabía qué todo el mundo entre los que me está haciendo que en lugar de simplemente definiéndola como NSObject. Sin embargo, mi protocolo incluso dijo que cualquiera que cumpla con ese protocolo también debe cumplir con el protocolo NSObject al hacer esto: OverlayDelegate <NSObject>, y aún así, el compilador no lo consiguió.

Así que por ahora estoy satisfecho de que funciona con el yeso, pero se siente como comer pescado viejo.

+0

Nota: Mientras escribía mi respuesta, apareció un mensaje que dtuckernet había enviado una respuesta. Entonces él era más rápido. – openfrog

+2

Se debe a que 'performSelector: withObject: afterDelay:' se define en 'NSObject' la clase en lugar de' NSObject' en el protocolo. Es por eso que tuvo errores (en ARC) y no apareció en la finalización del código. – mattjgalloway

+0

Tiene mucho sentido ahora. – openfrog

3

Simple, su objeto es del tipo id y se ajusta al protocolo NSObject. Sin embargo, este protocolo no declara performSelector:withObject:afterDelay:, por lo que ARC no sabe lo que hace el método y si debe retener algo. Use un objeto NSObject o cast it antes de hacer la llamada al método.

0

me encontré con error:

No known class method for selector conformsToProtocol:

La razón es que: nombre del archivo no es igual al nombre de la clase con @interface y @implementation.

Cuestiones relacionadas