Tecnicamente, è possibile ottenere l'accesso a un puntatore di funzione per il blocco. Ma è del tutto pericoloso farlo, quindi certamente non lo consiglio. Per vedere come, si consideri il seguente esempio:
#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);
}
}
esecuzione che i rendimenti:
Howdy 1
ret = 1
che è quello che ci si aspetterebbe da puramente esecuzione di quei blocchi direttamente con block()
. Quindi, è possibile utilizzare invoke
come puntatore funzione.
Ma come ho detto, questo è totalmente pericoloso. In realtà non usare questo!
Se volete vedere un write-up di un modo per fare quello che stai chiedendo, quindi check this out: http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html
E 'solo un grande write-up di quello che si avrebbe bisogno di fare per farlo funzionare. Purtroppo, non funzionerà mai su iOS (dal momento che è necessario contrassegnare una pagina come eseguibile che non è possibile fare all'interno della sandbox della tua app). Ma comunque, un grande articolo.
Si prega di scusare la mia ignoranza, ma perché è esattamente pericoloso? Suppongo sia perché la struttura è interna e potrebbe cambiare in futuro, giusto? –
Proprio così :-). – mattjgalloway
Il problema con questo è che richiede ancora di passare il blocco alla funzione invoke, mentre l'OP dice che non è possibile passare un contesto al callback. – newacct