1
objective-c의 블록 변수는 참조이며 다음 코드가 컴파일러에 의해 다른 형식으로 변환 될 수 있음을 알게되었습니다.블록 수명주기 함수?
원래 코드 :
typedef int (^block_type)();
block_type create_k(int i)
{
block_type block = ^(){
return i;
};
//[block copy];
return block;
}
생성 된 코드 :
typedef void (*generic_invoke_funcptr)(void *, ...);
struct __block_literal {
void *isa;
int flags;
int reserved;
generic_invoke_funcptr invoke;
struct __block_descriptor_tmp *descriptor;
const int captured_i;
};
static const struct __block_descriptor_tmp {
unsigned long reserved;
unsigned long literal_size;
/* no copy/dispose helpers needed */
} __block_descriptor_tmp = {
0UL, sizeof(struct __block_literal)
};
// ^int (void) { return i; }
int __create_k_block_invoke_(struct __block_literal *bp) {
return bp->captured_i;
}
typedef int (*iv_funcptr)(struct __block_literal *);
typedef int (^block_type)();
block_type create_k(int i)
{
//block_type block = ^(){
// return i;
//};
struct __block_literal __b = {
.isa = &_NSConcreteStackBlock,
.flags = BLOCK_HAS_DESCRIPTOR,
.reserved = 0,
.invoke = (generic_invoke_funcptr)__f_block_invoke_,
.descriptor = &__block_descriptor_tmp,
.captured_i = i
};
struct __block_literal *block = &__b;
return block;
}
그래서 | _ B | 스택 및 블록은 | _b |. | create_k | return | block |, 수신자는 잘못된 주소 만 가져옵니다.
그러나 간부 그것을 인쇄하여
int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
printf("%d\n", create_k(40)());
[pool drain];
return 0;
}
| 40 | 및 | 블록 | 유효한 블록입니다. 무슨 일이야?