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.
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)
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.
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