기술적으로 블록의 함수 포인터에 액세스 할 수 있습니다. 그러나 그렇게하는 것은 전적으로 안전하지 않으므로 나는 그것을 권장하지 않습니다. 다음 예제를 고려하는 방법을 보려면 :
#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);
}
}
는 실행이 수율 :
우리가 순수하게
block()
직접 그 블록을 실행에서 기대할 수있는 것입니다
Howdy 1
ret = 1
. 따라서 함수 포인터로 invoke
을 사용할 수 있습니다.
그러나 내가 말했듯이 이는 전적으로 안전하지 않습니다. 이것을 실제로 사용하지 마십시오! 당신은 당신이 요구하는지 무엇을 할 수있는 방법의 쓰기 업을 보려면
,이 체크 아웃 : http://www.mikeash.com/pyblog/friday-qa-2010-02-12-trampolining-blocks-with-mutable-code.html
그것은 당신이해야 할 것이 무엇 단지 좋은 쓰기이야 이것을 작동 시키려면. 안타깝게도, iOS에서는 작동하지 않습니다 (앱의 샌드 박스 내에서 수행 할 수없는 실행 파일로 페이지를 표시해야하기 때문에). 그럼에도 불구하고, 위대한 기사.
제 생각에는 변명의 여지가 없지만 안전하지 않은 이유는 무엇입니까? 구조체가 내부 구조이고 미래에 바뀔 수 있기 때문에 그것이 맞습니까? –
맞습니다 :-). – mattjgalloway
이 문제는 호출 블록에 컨텍스트를 전달할 수 없다는 OP와 달리 호출 블록에 블록을 전달해야한다는 것입니다. – newacct