2012-01-16 2 views
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 | 및 | 블록 | 유효한 블록입니다. 무슨 일이야?

답변

1

내 생각 엔 스택 프레임의 메모리가 아직 초기화되지 않았을 것입니다. 다른 임의의 데이터를 얻기 위해 create_k()와 printf() 사이에서 다른 함수를 호출 해보십시오.