Pergunta

O tipo IMP em Objective-C representa um ponteiro de função, tanto eu como entender. Existe alguma maneira de fazer uma IMP de um ponteiro de bloco? Obrigado por suas idéias.

Foi útil?

Solução

Uma vez que este foi escrito há agora API no iOS e Mac OS X que permite Blocks para ser transformado em PIM diretamente. Eu escrevi um weblog pós descrevendo o API (imp_implementationWithBlock ()).


Um bloco é efectivamente uma estrutura que contém um pouco de metadados, uma referência ao código contido no interior do bloco e uma cópia dos dados copiados-const capturados no interior do bloco.

Assim, não, não há nenhuma maneira para mapear directamente entre um IMP e uma referência de bloco.

Quando uma chamada a um bloco é compilado, o compilador emite um trampolim que configura o quadro de pilha e depois salta para o código executável dentro do bloco.

O que você pode fazer, porém, é criar um IMP, que atua como aquele trampolim. Para o seguinte, você precisará de um específico IMP para cada conjunto de argumentos e tipos de retorno a ser chamado. Se você precisa para tornar este genérico, você vai precisar usar montagem.

Por isso, eu sou a criação de instâncias de blocos únicos por instância da classe. Se você quer ter um bloco genérico que atua em todas as instâncias, construir um hash de SEL -.> Bloco por classe

(1) blocos associados ao actuar como PIM usando o mecanismo de referências associado. Algo como:

void (^implementingBlock)(id s, SEL _c, int v) = ^(id s, SEL _c, int v) {
     // do something here
}

objc_setAssociatedObject(obj, SELToImp, [implementingBlock copy]));

(2) implementar um trampolim IMP algo como isto:

void void_id_sel_intTramp(id self, SEL _cmd, int value) {
    int (^block)(id s, SEL _c, int v) = objc_getAssociatedObject(self, _cmd);
    block(self, _cmd, value);
}

(3) o material do trampolim acima em qualquer seletor via API do tempo de execução Objective-C (ver method_setImplementation e afins)

Advertências:

  • este foi digitado em StackOverflow. O código real será semelhante, mas provavelmente um pouco diferente.

  • o [cópia implementingBlock] é crítica; Blocos começar a vida na pilha (geralmente)

Outras dicas

Eu acredito que Mike Ash, com alguma ajuda de Landon Fuller, tem resolvido este para o caso geral, incluindo iOS, que é mais difícil. Ele tem uma aula sobre github que vai virar um bloco em um ponteiro de função.

Você também pode querer conferir o anúncio e alguns interessante discussão de acompanhamento sobre o cacau-independente.

UPDATE:. E agora há imp_implementationWithBlock() como acima referido

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top