objective-c self objective-c-blocks

objective c - ¿Llamar a[self methodName] desde dentro de un bloque?



objective-c objective-c-blocks (5)

Acabo de toparme con bloques y creo que son justo lo que estoy buscando, excepto por una cosa: ¿es posible llamar a un método [self methodName] desde dentro de un bloque?

Esto es lo que trato de hacer:

-(void)someFunction{ Fader* fader = [[Fader alloc]init]; void (^tempFunction)(void) = ^ { [self changeWindow:game]; //changeWindow function is located in superclass }; [fader setFunction:tempFunction]; }

He estado buscando por un par de días y no puedo encontrar ninguna evidencia de que esto sea posible.

¿Es esto posible, o estoy tratando de usar bloques para algo para lo que no están destinados?

La razón por la que estoy usando bloques es que he creado una clase de Fader, y quiero almacenar un bloque para que se ejecute cuando termine de desvanecerse.

Gracias

EDITAR: Bien, agregué la sugerencia, pero sigo recibiendo un error de EXC_BAD_ACCESS ...

-(void)someFunction{ Fader* fader = [[Fader alloc]init]; __block MyScreen* me = self; void (^tempFunction)(void) = ^ { [me changeWindow:game]; //changeWindow function is located in superclass }; [fader setFunction:tempFunction]; [fader release]; }

Tal vez no estoy autorizado a dar la función de fader ...?


¿Es posible llamar a un método [self methodName] desde dentro de un bloque?

Si por qué no. Si su tempFunction es un método de instancia, puede hacerlo. El método llamado debe ser accesible es la única restricción.


La respuesta aceptada está desactualizada . ¡Usar __block en ese caso puede causar errores!

Para evitar este problema, es una buena práctica capturar una referencia débil a self , como esta:

- (void)configureBlock { XYZBlockKeeper * __weak weakSelf = self; self.block = ^{ [weakSelf doSomething]; // capture the weak reference // to avoid the reference cycle } }

Consulte la documentación de Apple: evite los ciclos de referencia potentes al capturarse para obtener más información.


Me pregunto si [fader setFunction: tempFunction]; entonces es síncrono o asíncrono. los bloques se insertan en stack.so en MRR, si no lo retienes, se disparará.

-(void)someFunction{ Fader* fader = [[Fader alloc]init]; void (^tempFunction)(void) = ^ { [self changeWindow:game]; //changeWindow function is located in superclass }; [fader setFunction:tempFunction]; //if the tempFunction execute there will be right. }//there the tempFunction pop off //....some thing go on //execute the tempFunction will go wrong.


Sí, usted puede hacer esto.

Tenga en cuenta, sin embargo, que el bloque se mantendrá. Si termina almacenando este bloque en un ivar, puede crear fácilmente un ciclo de retención, lo que significa que ninguno de ellos será desasignado.

Para evitar esto, puede hacer:

- (void) someMethodWithAParameter:(id)aParameter { __block MySelfType *blocksafeSelf = self; void (^tempFunction)(void) = ^ { [blocksafeSelf changeWindow:game]; }; [self doSomethingWithBlock:tempFunction]; }

La palabra clave __block significa (entre otras cosas) que el objeto al que se hace referencia no se conservará.


__block CURRENTViewController *blocksafeSelf = self; [homeHelper setRestAsCheckIn:strRestId :^(NSObject *temp) { [blocksafeSelf YOURMETHOD:params]; }];