关于block
void pr (int (^block)(void)) {
printf("%d\n",block());
}
int (^g)(void) = ^{
return 100;
};
void func1 (int n) {
int (^b1)(void) = ^{
return n;
};
pr(b1);
g = b1;
}
void func2 (int n) {
int a = 10;
int (^b2)(void) = ^{
return n*a;
};
pr(b2);
}
int main(int argc, char * argv[]) {
@autoreleasepool {
pr(g);
func1(15);
func2(5);
pr(g);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
这段代码在MRC和ARC下的输出结果是不一样的
MARC环境下的输出结果
image.png
ARC环境下的输出结果
image.png
之所以在MRC环境下输出的结果不为 100、15、50、15,是因为函数内的block的生命周期和自动变量一样,当执行函数时block的内存会被保存在栈上,当func1执行完毕后块b1的生命周期也随之结束。(我猜想)当再次调用pr(g)时调用的是依旧保留在栈区的pr函数和pr函数中保存的b2(此时该内存块还没有被从栈中弹出),但是如果此时pr已经出栈,则会出现错误。
如果想要解决该错误只需使用Block_copy()函数对b1进行一次拷贝,Block_copy()函数会讲栈区的block拷贝一份到堆区此时g便指向对区的b1了。
void func1 (int n) {
int (^b1)(void) = ^{
return n;
};
pr(b1);
g = Block_copy(b1);
}
image.png
而在ARC环境下会自动对block进行一次拷贝。
网友评论