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 |和|块|是一个有效的块。怎么了?
答案 0 :(得分:1)
我的猜测是该堆栈帧的内存尚未归零。尝试在create_k()和printf()之间调用另一个函数来获取其中的一些其他随机数据。