Question

Le type IMP dans Objective-C représente un pointeur de fonction, pour autant que je sache. Est-il possible de créer un IMP à partir d'un pointeur de bloc? Merci pour vos idées.

Était-ce utile?

La solution

Depuis que cela a été écrit, il existe maintenant une API dans iOS et Mac OS X qui permet de transformer directement les blocs en IMP. J'ai rédigé un article de blog décrivant le API (imp_implementationWithBlock ()).

Un bloc est en réalité une structure contenant un bit de métadonnées, une référence au code contenu dans le bloc et une copie des données copiées par const capturées dans le bloc.

Ainsi, non, il n’existe aucun moyen de mapper directement entre un IMP et une référence de bloc.

Lorsqu'un appel à un bloc est compilé, le compilateur émet un trampoline qui configure le cadre de la pile, puis passe au code exécutable du bloc.

Cependant, vous pouvez créer un IMP qui agit comme un trampoline. Pour ce qui suit, vous aurez besoin d’un IMP spécifique pour chaque ensemble d’arguments & amp; retourne les types à appeler. Si vous devez créer ce générique, vous devez utiliser l'assemblage.

Pour cela, je configure des instances de bloc uniques par instance de la classe. Si vous souhaitez avoir un bloc générique qui agit dans toutes les instances, créez un hachage SEL - > bloc par classe.

(1) Associez des blocs pour qu'ils agissent comme des IMP à l'aide du mécanisme de références associé. Quelque chose comme:

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

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

(2) implémenter un trampoline IMP comme ceci:

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) insère le trampoline ci-dessus dans n'importe quel sélecteur via l'API du runtime d'Objective-C (voir method_setImplementation et similaires)

Mises en garde:

  • cela a été saisi dans StackOverflow. Le code réel sera similaire mais probablement légèrement différent.

  • la [implementationBlock copy] est critique; Les blocs commencent la vie sur la pile (généralement)

Autres conseils

Je pense que Mike Ash, avec l’aide de Landon Fuller, a résolu ce problème dans le cas général, y compris iOS, ce qui est plus difficile. Il a une classe sur github qui transformera un bloc en un pointeur de fonction.

Vous pouvez également vouloir conférer la

scroll top