Frage

Der IMP Typ in Objective-C stellt einen Funktionszeiger, so weit ich als verstehen. Gibt es eine Möglichkeit, um eine IMP aus einem Block Zeiger zu machen? Vielen Dank für Ihre Ideen.

War es hilfreich?

Lösung

Da dies geschrieben wurde, gibt es jetzt API in iOS und Mac OS X, die direkt Blocks werden verwandelte sich in IMPs können. Ich schrieb auf einen Weblog Beitrag beschreibt die API (imp_implementationWithBlock ()).


Ein Block ist effektiv eine Struktur, die ein wenig von Metadaten enthält, eine Referenz auf den Code innerhalb des Blocks und eine Kopie der const kopierten Daten innerhalb des Blocks erfasst enthalten sind.

So, nein, gibt es keine Möglichkeit, direkt zwischen einer IMP und einer Block-Referenzkarte.

Wenn zu einem Block einen Anruf zusammengestellt ist, gibt der Compiler ein Trampolin, das den Stapelrahmen einrichtet und springt dann auf den Programmcode innerhalb des Blocks.

Was Sie tun können, obwohl, ist einen IMP zu schaffen, wie das Trampolin fungiert. Für die folgenden, müssen Sie eine bestimmte IMP für jeden Satz von Argumenten und Rückgabetypen aufgerufen werden. Wenn Sie diese generische machen müssen, müssen Sie Montage verwenden.

Dazu Ich gründe einzigartige Blockinstanzen pro Instanz der Klasse auf. Wenn Sie einen generischen Block haben wollen, die über alle Instanzen hinweg wirkt, bauen einen Hash SEL -.> Block pro Klasse

(1) assoziierte Blöcke als IMPs wirken, um die zugehörigen Referenzen Mechanismus. So etwas wie:

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

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

(2) führen ein Trampolin IMP etwas wie folgt aus:

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) stopfen das oben Trampolin in für jeden Wähler über die Objective-C-Laufzeit des API (siehe method_setImplementation und dergleichen)

Caveats:

  • Dieses wurde in Stackoverflow getippt. Der eigentliche Code wird ähnlich sein, aber wahrscheinlich etwas anders aus.

  • die [implementingBlock Kopie] ist von entscheidender Bedeutung; Blöcke beginnen Leben auf dem Stapel (in der Regel)

Andere Tipps

ich glaube, Mike Ash, mit etwas Hilfe von Landon Fuller, das für den allgemeinen Fall gelöst hat, einschließlich iOS, das härter ist. Er hat eine Klasse auf Github , die einen Block in einen Funktionszeiger drehen wird.

Sie können auch die Ankündigung verleihen und einige interessante Follow-up-Diskussion über Kakao-ungebunden.

UPDATE:. Und jetzt ist es imp_implementationWithBlock() gemäß oben

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top