Domanda

Il tipo IMP in Objective-C rappresenta un puntatore a funzione, per quanto ne so. Esiste un modo per creare un IMP da un puntatore a blocco? Grazie per le tue idee.

È stato utile?

Soluzione

Da quando è stato scritto, ora c'è l'API in iOS e Mac OS X che consente ai blocchi di essere trasformati direttamente in IMP. Ho scritto un post sul blog descrivendo il API (imp_implementationWithBlock ()).


Un blocco è effettivamente una struttura che contiene un po 'di metadati, un riferimento al codice contenuto nel blocco e una copia dei dati cop copiati catturati all'interno del blocco.

Pertanto, no, non esiste alcun modo per mappare direttamente tra un IMP e un riferimento di blocco.

Quando viene compilata una chiamata a un blocco, il compilatore emette un trampolino che imposta il frame dello stack e quindi passa al codice eseguibile all'interno del blocco.

Quello che puoi fare, però, è creare un IMP che si comporta come quel trampolino. Di seguito, avrai bisogno di un IMP specifico per ogni set di argomenti & amp; restituisce i tipi da chiamare. Se devi creare questo generico, dovrai usare assembly.

Per questo, sto configurando istanze di blocco uniche per istanza della classe. Se vuoi avere un blocco generico che agisca in tutte le istanze, crea un hash di SEL - > blocco per classe.

(1) Associa i blocchi per agire come IMP usando il meccanismo di riferimenti associato. Qualcosa del tipo:

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

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

(2) implementano un IMP per trampolino simile a questo:

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) inserisce il trampolino di cui sopra per qualsiasi selettore tramite l'API del runtime di Objective-C (vedi method_setImplementation e simili)

Avvertenze:

  • questo è stato digitato in StackOverflow. Il vero codice sarà simile, ma probabilmente leggermente diverso.

  • la [copia di implementingBlock] è fondamentale; I blocchi iniziano la vita in pila (di solito)

Altri suggerimenti

Credo che Mike Ash, con l'aiuto di Landon Fuller, abbia risolto questo problema nel caso generale, incluso iOS, che è più difficile. Ha una lezione su github che trasformerà un blocco in un puntatore a funzione.

Potresti anche voler conferire annuncio e alcuni interessante discussione di follow-up sul cacao non legato.

AGGIORNAMENTO: E ora c'è imp_implementationWithBlock () come indicato sopra.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top