So, I'm trying to pass a block as an NSAlert
contextInfo
parameter.
[myAlert beginSheetModalForWindow: theWindow
modalDelegate: myAlert
didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:)
contextInfo: (void *) aBlock];
and get it back on the other end:
void (^responseBlock)() = (__bridge_transfer void (^)()) contextInfo;
Which works, to an extent. Before my call to beginSheetModalForWindow:...
aBlock is at 0x00007fff610e1ec0
, and in the response (alertDidEnd:...
), contextInfo is at 0x00007fff610e1ec0
.
However, when I try to call the block:
responseBlock();
I get the following error
error: called object type '__block_literal_generic *' is not a function or function pointer
error: 1 errors parsing expression
How does one properly cast blocks to an from void *
s for the sake of simple transference?
Edit:
Full attempted code, using the cast methods suggested in the answers. I now receive an EXC_BAD_ACCESS error on the responseBlock();
call.
- (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;
}
}
}
Other Notes:
When using __bridge
, the memory address of responseBlock
and contextInfo
are different, whereas with __bridge_transfer
, they are the same. Neither alleviates the EXC_BAD_ACCESS issue.
[myAlert beginSheetModalForWindow: theWindow
modalDelegate: myAlert
didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:)
contextInfo: (__bridge_retained void *) [aBlock copy]];
and later...
void (^responseBlock)() = (__bridge_transfer typeof(responseBlock)) contextInfo;
Here's a small example. I think that the problem with your code is that you are trying to use __bridge_transfer
with a void *
which isn't memory managed with ARC:
void takesBlock(void *asPointer)
{
void (^asBlock)() = (__bridge typeof asBlock) asPointer;
asBlock();
}
int main()
{
@autoreleasepool {
takesBlock((__bridge void *)[^{
NSLog(@"Hello World!");
} copy]);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With