所以,我正在尝试将一个块作为NSAlert
contextInfo
参数传递。
[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
。
但是,当我尝试调用块时:
responseBlock();
我收到以下错误
错误:调用对象类型'__block_literal_generic *'不是函数或函数指针
错误:解析表达式时出错1个
为了简单的转移,如何将块正确地转换为来自void *
的块?
修改
完整的尝试代码,使用答案中建议的强制转换方法。我现在在responseBlock();
电话上收到EXC_BAD_ACCESS错误。
- (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问题。
[myAlert beginSheetModalForWindow: theWindow
modalDelegate: myAlert
didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:)
contextInfo: (__bridge_retained void *) [aBlock copy]];
以后......
void (^responseBlock)() = (__bridge_transfer typeof(responseBlock)) contextInfo;
答案 0 :(得分:6)
这是一个小例子。我认为您的代码存在的问题是您尝试将__bridge_transfer
与void *
一起使用,而void takesBlock(void *asPointer)
{
void (^asBlock)() = (__bridge typeof asBlock) asPointer;
asBlock();
}
int main()
{
@autoreleasepool {
takesBlock((__bridge void *)[^{
NSLog(@"Hello World!");
} copy]);
}
}
不是由ARC管理的内存:
{{1}}