美文网首页精品文章iOS
《Objective-C高级编程》Blocks 阅读笔记 ite

《Objective-C高级编程》Blocks 阅读笔记 ite

作者: dibadalu | 来源:发表于2016-02-17 19:35 被阅读129次

    《Objective-C高级编程》Blocks 阅读笔记系列

    《Objective-C高级编程》Blocks 阅读笔记 item1(Blocks概要和模式)
    《Objective-C高级编程》Blocks 阅读笔记 item2(Block的实质)
    《Objective-C高级编程》Blocks 阅读笔记 item3(截获自动变量值)
    《Objective-C高级编程》Blocks 阅读笔记 item4(__block说明符)
    《Objective-C高级编程》Blocks 阅读笔记 item5(Block存储域)
    《Objective-C高级编程》Blocks 阅读笔记 item6(__block变量存储域)
    《Objective-C高级编程》Blocks 阅读笔记 item7(截获对象)
    《Objective-C高级编程》Blocks 阅读笔记 item8(__block变量和对象)
    《Objective-C高级编程》Blocks 阅读笔记 item9(Block循环引用)
    《Objective-C高级编程》Blocks 阅读笔记 item10(copy/release实例方法)

    2.3 Blocks的实现

    2.3.5 __block变量存储域

    从“Block存储域”一节可知,*** 使用__block变量的Block从栈复制到堆上时,__block变量也会受到影响。 ***
    表 Block从栈复制到堆时对__block变量产生的影响

    __block变量的配置存储域 Block从栈复制到堆时的影响
    从栈复制到堆并被Block持有
    被Block持有

    *** 在一个Block中使用__block变量 ***

    Snip20160217_20.png

    *** 在多个Block中使用__block变量 ***

    Snip20160217_21.png

    *** Block的废弃和__block变量的释放 ***

    Snip20160217_22.png

    遗留的问题

    “Block存储域”一节中遗留的问题:

    • 使用__block变量的结构体成员变量__forwarding的原因

    *** 不管__block变量配置在栈上还是在堆上,都能够正确地访问该变量 ***
    正如这句话所诉,通过Block的复制,__block变量也会从栈复制到堆上。此时可同时访问栈上的__block变量和堆上的__block变量。

    __block int val = 0;  // __block变量
    
    void (^blk)(void) = [^{++val;} copy]; // Block
    
    ++val;
    
    blk();
    
    NSLog(@"%d", val);
    
    

    利用copy方法复制使用了__block变量的Block语法。此时,Block和__block变量均从栈复制到堆。

    *** 在Block语法表达式中,使用初始化后的__block变量 ***

    ^{++val;}
    

    *** 在Block语法表达式之后,使用与Block无关的__block变量 ***

    ++val;
    

    然而,以上两种源代码都可以转换为:

    ++(val.__forwaring->val);
    

    在变化Block语法的函数中,该变量val为 *** 复制到堆上的__block变量的结构体实例 ,而使用与Block无关的变量val,为 复制前栈上的__block变量的结构体实例 ***。

    但是,栈上的__block变量的结构体实例(即变量val)在__block变量从栈复制到堆上时,会将成员变量__forwarding的值替换为复制目标堆上的__block变量的结构体实例的地址

    Snip20160217_24.png

    相关文章

      网友评论

        本文标题:《Objective-C高级编程》Blocks 阅读笔记 ite

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