2012-06-19 6 views
13

Also, ich versuche, einen Block als NSAlertcontextInfo Parameter übergeben.Wie gießt Blöcke zu und von void *

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

und bekommen es am anderen Ende zurück:

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

Welche, in einem Umfang funktioniert. Vor meinem Anruf an beginSheetModalForWindow:... aBlock ist bei 0x00007fff610e1ec0, und in der Antwort (alertDidEnd:...) ist ContextInfo bei 0x00007fff610e1ec0.

aber wenn ich versuche, um den Block zu nennen:

responseBlock(); 

ich die folgende Fehlermeldung erhalten

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

Wie kann man richtig Blocks von void * s aus Gründen der einfachen Übertragung auf ein Guss ?

Bearbeiten: Vollständig versuchten Code, mit den Cast-Methoden in den Antworten vorgeschlagen. Ich erhalte jetzt einen Fehler EXC_BAD_ACCESS auf dem Aufruf 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; 
     } 
    } 
} 

Weitere Anmerkungen: Wenn __bridge verwenden, die Speicheradresse des responseBlock und contextInfo unterschiedlich sind, während bei __bridge_transfer, sie gleich sind. Weder verringert das Problem EXC_BAD_ACCESS.

ARBEITEN:

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

und später ...

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

Ich habe eine Antwort, aber ich kann das Problem nicht reproduzieren. Ich frage mich, warum das so ist ... Hast du zusätzliche Warn-/Compile-Flags? –

Antwort

6

Hier ist ein kleines Beispiel. Ich denke, dass das Problem mit Ihrem Code ist, dass Sie versuchen, __bridge_transfer mit einem void * zu verwenden, die keinen Speicher mit ARC verwaltet wird:

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;' gibt mir den Syntaxfehler: 'Expected ')'' auf 'responseBlock' in' typeof responseBlock'. Gedanken? –

+0

@pcperini können Sie den Inhalt der Funktion in einen Pastenbehälter posten? –

+0

Die Frage wurde um die vollständige Funktion erweitert. Der Fehler hat sich von einem Typfehler zu einem vollständigen EXC_BAD_ACCESS geändert. –

Verwandte Themen