2012-06-19 8 views
13

Tak, próbuję przekazać blok jako parametr NSAlertcontextInfo.Jak odlewać bloki do iz pustki *

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

i dostać go z powrotem na drugim końcu:

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

Który działa, do pewnego stopnia. Przed moim wywołaniem do beginSheetModalForWindow:... aBlock jest na 0x00007fff610e1ec0, a w odpowiedzi (alertDidEnd:...), contextInfo jest na 0x00007fff610e1ec0.

Jednak gdy próbuję wywołać blok:

responseBlock(); 

I pojawia się następujący błąd

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

jaki sposób można prawidłowo oddanych bloków z void * s przez wzgląd na prostym przeniesieniu ?

Edytuj: Pełna próba kodu, za pomocą metod obsadzania sugerowanych w odpowiedziach. Otrzymuję teraz błąd EXC_BAD_ACCESS w wywołaniu 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; 
     } 
    } 
} 

Inne uwagi: Podczas korzystania __bridge, adres pamięci responseBlock i contextInfo są różne, natomiast z __bridge_transfer, że są takie same. Ani nie zmniejsza problemu EXC_BAD_ACCESS.

PRACY:

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

a później ...

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

mam odpowiedź, ale nie mogę odtworzyć problem. Zastanawiam się, dlaczego tak jest ... czy masz jakieś dodatkowe flagi ostrzegające/kompilujące? –

Odpowiedz

6

Oto mały przykład. Myślę, że problem z kodem jest to, że starają się wykorzystywać __bridge_transfer z void * pamięć, która nie jest zarządzany z łuku:

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;' daje mi błąd składniowy: 'Oczekiwany ')' 'on' responseBlock' w' typeof responseBlock'. Myśli? –

+0

@pcperini Czy możesz umieścić zawartość funkcji w pojemniku na pastele? –

+0

Dodano pełną funkcję do pytania. Błąd zmienił się z błędu typu na pełny EXC_BAD_ACCESS. –