美文网首页
知识点总结

知识点总结

作者: JazzP | 来源:发表于2017-06-29 15:44 被阅读20次

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

    相关文章

      网友评论

          本文标题:知识点总结

          本文链接:https://www.haomeiwen.com/subject/rqimcxtx.html