Technicznie można uzyskać dostęp do wskaźnika funkcji dla bloku. Ale jest to całkowicie niebezpieczne, więc z pewnością nie polecam tego. Aby zobaczyć, jak Rozważmy następujący przykład:
#import <Foundation/Foundation.h>
struct Block_layout {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
};
int main(int argc, char *argv[]) {
@autoreleasepool {
// Block that doesn't take or return anything
void(^block)() = ^{
NSLog(@"Howdy %i", argc);
};
// Cast to a struct with the same memory layout
struct Block_layout *blockStr = (struct Block_layout *)(__bridge void *)block;
// Now do same as `block()':
blockStr->invoke(blockStr);
// Block that takes an int and returns an int
int(^returnBlock)(int) = ^int(int a){
return a;
};
// Cast to a struct with the same memory layout
struct Block_layout *blockStr2 = (struct Block_layout *)(__bridge void *)returnBlock;
// Now do same as `returnBlock(argc)':
int ret = ((int(*)(void*, int a, ...))(blockStr2->invoke))(blockStr2, argc);
NSLog(@"ret = %i", ret);
}
}
Running że plony:
Howdy 1
ret = 1
Która jest to, czego oczekujemy od czysto wykonywania tych bloków bezpośrednio z block()
. Więc możesz użyć invoke
jako wskaźnika funkcji.
Ale jak mówię, jest to całkowicie niebezpieczne. Nie używaj tego!
Jeśli chcesz zobaczyć write-up na drodze do zrobienia to pytasz, to sprawdź to: http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html
To tylko wielki write-up, co trzeba zrobić aby to zadziałało. Niestety, nigdy nie będzie działać na iOS (ponieważ musisz oznaczyć stronę jako plik wykonywalny, którego nie możesz wykonywać w piaskownicy twojej aplikacji). Ale mimo to świetny artykuł.
Proszę wybaczyć moją ignorancję, ale dlaczego tak naprawdę jest to niebezpieczne? Przypuszczam, że to dlatego, że struktura jest wewnętrzna i może się zmienić w przyszłości, prawda? –
Zgadza się :-). – mattjgalloway
Problem z tym, że nadal wymaga przekazania bloku do funkcji invoke, podczas gdy OP mówi, że nie można przekazać kontekstu do wywołania zwrotnego. – newacct