14

所以,我试图将一个块作为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 *为了简单的转移,如何正确地将块转换为 from ?

编辑: 完整的尝试代码,使用答案中建议的强制转换方法。我现在在通话中收到 EXC_BAD_ACCESS 错误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;
        }
    }
}

其他说明: 使用时和__bridge的内存地址不同,使用时相同。两者都不能缓解 EXC_BAD_ACCESS 问题。responseBlockcontextInfo__bridge_transfer

在职的:

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

然后...

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

1 回答 1

7

这是一个小例子。我认为您的代码的问题在于您正在尝试使用__bridge_transfer不是void *由 ARC 管理的内存:

void takesBlock(void *asPointer)
{
    void (^asBlock)() = (__bridge typeof asBlock) asPointer;

    asBlock();
}

int main()
{
    @autoreleasepool {
        takesBlock((__bridge void *)[^{
            NSLog(@"Hello World!");
        } copy]);
    }
}
于 2012-06-19T17:37:45.010 回答