如何铸造块和从void * [英] How to cast blocks to and from void *
问题描述
所以,我试图传递一个块作为 NSAlert
contextInfo
参数。
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];
并返回另一端:
void (^responseBlock)() = (__bridge_transfer void (^)()) contextInfo;
这在一定程度上起作用。在我调用 beginSheetModalForWindow:...
之前,aBlock在 0x00007fff610e1ec0
,并在响应( alertDidEnd:...
),contextInfo位于 0x00007fff610e1ec0
。
Which works, to an extent. Before my call to beginSheetModalForWindow:...
aBlock is at 0x00007fff610e1ec0
, and in the response (alertDidEnd:...
), contextInfo is at 0x00007fff610e1ec0
.
当我尝试调用块:
responseBlock();
我收到以下错误
错误:调用的对象类型__block_literal_generic *不是函数或函数指针
错误:解析表达式时出现错误
error: called object type '__block_literal_generic *' is not a function or function pointer
error: 1 errors parsing expression
为了简单的转移,如何正确地从 void *
转换块?
How does one properly cast blocks to an from void *
s for the sake of simple transference?
修改:
完整尝试的代码,使用答案中建议的投放方法。我现在在 responseBlock();
调用上收到一个EXC_BAD_ACCESS错误。
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;
}
}
}
使用 __ bridge
时,内存地址 responseBlock
和 contextInfo
是不同的,而 __ bridge_transfer
,它们是相同的。既不缓解EXC_BAD_ACCESS问题。
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]];
及更高版本...
void (^responseBlock)() = (__bridge_transfer typeof(responseBlock)) contextInfo;
推荐答案
我认为你的代码的问题是你试图使用 __ bridge_transfer
与 void *
这不是用ARC管理的内存:
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]);
}
}
这篇关于如何铸造块和从void *的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!