Cómo lanzar bloques desde y hacia el vacío *
Entonces, estoy tratando de pasar un bloque comoNSAlert
contextInfo
parámetro.
[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;
Lo que funciona, hasta cierto punto. Antes de mi llamada abeginSheetModalForWindow:...
aBlock está en0x00007fff610e1ec0
, y en la respuesta (alertDidEnd:...
), contextInfo está en0x00007fff610e1ec0
.
Sin embargo, cuando intento llamar al bloque:
responseBlock();
Obtuve el siguiente error
error: el tipo de objeto llamado '__block_literal_generic *' no es una función o puntero de función
error: 1 errores al analizar la expresión
¿Cómo se funden correctamente los bloques a los devoid *
s por el simple hecho de la transferencia?
Editar: Intento de código completo, utilizando los métodos de conversión sugeridos en las respuestas. Ahora recibo un error EXC_BAD_ACCESS en elresponseBlock();
llamada.
- (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: Cuando usas__bridge
, la dirección de memoria deresponseBlock
ycontextInfo
son diferentes, mientras que con__bridge_transfer
, ellos son lo mismo. Ninguno de los dos alivia el problema EXC_BAD_ACCESS.
[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;