Tworzenie IMP z bloku Objective-C

Typ IMP w Objective-C reprezentuje wskaźnik funkcji, o ile rozumiem. Czy jest jakiś sposób na wykonanie IMP ze wskaźnika blokowego? Dzięki za pomysły.

Author: Jonathan Sterling, 2009-11-26

2 answers

Ponieważ to zostało napisane, istnieje teraz API w systemach iOS i Mac OS X, które umożliwia bezpośrednie przekształcanie bloków w chochliki. Napisałem post weblog opisujący API (imp_implementationWithBlock ()).


Blok jest w rzeczywistości strukturą, która zawiera bit metadanych, odniesienie do kodu zawartego w bloku i kopię const-skopiowanych danych przechwyconych w bloku.

Tak więc, nie, nie ma możliwości bezpośredniego odwzorowania pomiędzy IMP a blokiem Referencja.

Gdy wywołanie bloku jest kompilowane, kompilator emituje trampolinę, która ustawia ramkę stosu, a następnie przeskakuje do kodu wykonywalnego w obrębie bloku.

To, co możesz zrobić, to stworzyć IMPA, który działa jak ta trampolina. Dla następujących, you will need one specific IMP for each set of arguments & return types to be called. Jeśli chcesz stworzyć ten rodzaj, musisz użyć assembly.

W tym celu konfiguruję unikalne instancje blokowe na instancja klasy. Jeśli chcesz mieć ogólny blok, który działa we wszystkich instancjach, zbuduj hash SEL - > block na klasę.

(1) kojarzy bloki, aby działały jako IMPs przy użyciu mechanizmu powiązanych odniesień. Coś w stylu:

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

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

(2) zaimplementuj trampolinę IMP coś takiego:

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) wepchnij powyższą trampolinę do dowolnego selektora poprzez API runtime Objective-C (zobacz method_setImplementation i podobne)

Zastrzeżenia:

  • Wpisano do StackOverflow. Prawdziwy kod będzie podobny, ale prawdopodobnie nieco inny.

  • [implementingBlock copy] jest krytyczna; bloki rozpoczynają życie na stosie (Zwykle)

 27
Author: bbum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-20 17:48:07

Wierzę, że Mike Ash, z pomocą Landona Fullera, rozwiązał tę sprawę, w tym iOS, co jest trudniejsze. Posiada klasę na github , która zamieni blok w wskaźnik funkcji.

Możesz również przekazać ogłoszenie i kilka ciekawych dyskusji na temat cocoa-unbound.

UPDATE: a teraz jest imp_implementationWithBlock() jak wspomniano powyżej.

 10
Author: Clay Bridges,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-28 13:47:26