2012-06-19 22 views
13

Por lo tanto, estoy tratando de pasar un bloque como un parámetro NSAlertcontextInfo.Cómo lanzar bloques hacia y desde el vacío *

[myAlert beginSheetModalForWindow: theWindow 
        modalDelegate: myAlert 
        didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:) 
         contextInfo: (void *) aBlock]; 

y recuperarlo en el otro extremo:

void (^responseBlock)() = (__bridge_transfer void (^)()) contextInfo; 

que funciona, hasta cierto punto. Antes de llamar a beginSheetModalForWindow:... aBlock está en 0x00007fff610e1ec0, y en la respuesta (alertDidEnd:...), contextInfo está en 0x00007fff610e1ec0.

Sin embargo, cuando intento llamar el bloque:

responseBlock(); 

me sale el siguiente error

error: called object type '__block_literal_generic *' is not a function or function pointer
error: 1 errors parsing expression

¿Cómo se puede adecuadamente fundido bloques a una de void * s en aras de la simple transmisión ?

Editar: Código de intento completo, utilizando los métodos de conversión sugeridos en las respuestas. Ahora recibo un error EXC_BAD_ACCESS en la llamada responseBlock();.

- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo 
{ 
    void (^responseBlock)() = (__bridge typeof(responseBlock)) contextInfo; 

    switch (returnCode) 
    { 
     case NSCancelButton: 
     { 
      break; 
     } 

     case NSOKButton: 
     { 
      responseBlock(); 
      break; 
     } 
    } 
} 

Otras Notas: Al utilizar __bridge, la dirección de memoria de responseBlock y contextInfo son diferentes, mientras que con __bridge_transfer, que son los mismos. Ninguno alivia el problema EXC_BAD_ACCESS.

DE TRABAJO:

[myAlert beginSheetModalForWindow: theWindow 
        modalDelegate: myAlert 
        didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:) 
         contextInfo: (__bridge_retained void *) [aBlock copy]]; 

y después ...

void (^responseBlock)() = (__bridge_transfer typeof(responseBlock)) contextInfo; 
+0

tengo una respuesta, pero no puede reproducir el problema. Me pregunto por qué es eso ... ¿tiene alguna bandera de advertencia/compilación adicional? –

Respuesta

6

Aquí hay un pequeño ejemplo. Creo que el problema con el código es que usted está tratando de utilizar __bridge_transfer con un void * que no es memoria administrada con ARC:

void takesBlock(void *asPointer) 
{ 
    void (^asBlock)() = (__bridge typeof asBlock) asPointer; 

    asBlock(); 
} 

int main() 
{ 
    @autoreleasepool { 
     takesBlock((__bridge void *)[^{ 
      NSLog(@"Hello World!"); 
     } copy]); 
    } 
} 
+0

'void (^ responseBlock)() = (__bridge typeof responseBlock) contextInfo;' me da el error de sintaxis: 'Esperado ')'' en 'responseBlock' en' typeof responseBlock'. ¿Pensamientos? –

+0

@pcperini puede publicar el contenido de la función en un contenedor de pasta? –

+0

Agregó la función completa a la pregunta. El error ha cambiado de un error de tipo a un EXC_BAD_ACCESS completo. –

Cuestiones relacionadas