14

NSAlert contextInfoそのため、ブロックをパラメーターとして渡そうとしています。

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

反対側でそれを取り戻します:

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

これはある程度機能します。beginSheetModalForWindow:...aBlockへの呼び出しが at になる前0x00007fff610e1ec0、および応答 ( alertDidEnd:...) では、contextInfo は at0x00007fff610e1ec0です。

ただし、ブロックを呼び出そうとすると:

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

ここに小さな例があります。あなたのコードの問題は、ARCで管理されたメモリではない を使用しようとしていることだと思い__bridge_transferますvoid *:

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 に答える