如何在空白之间施放区块*

时间:2012-06-19 17:30:49

标签: objective-c casting objective-c-blocks void-pointers

所以,我正在尝试将一个块作为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时,responseBlockcontextInfo的内存地址不同,而__bridge_transfer的内存地址则相同。两者都没有缓解EXC_BAD_ACCESS问题。

WORKING:

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

以后......

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

1 个答案:

答案 0 :(得分:6)

这是一个小例子。我认为您的代码存在的问题是您尝试将__bridge_transfervoid *一起使用,而void takesBlock(void *asPointer) { void (^asBlock)() = (__bridge typeof asBlock) asPointer; asBlock(); } int main() { @autoreleasepool { takesBlock((__bridge void *)[^{ NSLog(@"Hello World!"); } copy]); } } 不是由ARC管理的内存:

{{1}}