知识点总结

关于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进行一次拷贝。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容