Tak, próbuję przekazać blok jako parametr NSAlert
contextInfo
.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;
mam odpowiedź, ale nie mogę odtworzyć problem. Zastanawiam się, dlaczego tak jest ... czy masz jakieś dodatkowe flagi ostrzegające/kompilujące? –