8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

'__block' 关键字是什么意思?

Tomáš Zato 2月前

60 0

Objective-C 中的 __block 关键字到底是什么意思?我知道它允许您修改块内的变量,但我想知道... 它到底告诉编译器什么?它有什么作用吗?

到底是什么 __block 意思?我知道它允许您修改块内的变量,但我想知道...

  1. 它到底告诉编译器什么?
  2. 它还有其他作用吗?
  3. 如果它的作用仅此而已,那为什么首先需要它呢?
  4. 它在文档中的任何地方吗?(我找不到它)。
帖子版权声明 1、本帖标题:'__block' 关键字是什么意思?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Tomáš Zato在本站《objective-c》版块原创发布, 转载请注明出处!
最新回复 (0)
  • @Code Monkey:我问的是关键字,而不是一般的语法。所以不要认为它真的是重复的。

  • 它告诉编译器,任何用它标记的变量在块内使用时都必须以特殊方式处理。通常,块中使用的变量及其内容会被复制,因此对这些变量所做的任何修改都不会显示在块外。当它们被标记为 时 __block ,块内所做的修改也会在块外可见。

    有关示例和更多信息,请参阅 Apple 的 Blocks 编程主题 __block 存储类型 .

    重要的例子是这个:

    extern NSInteger CounterGlobal;
    static NSInteger CounterStatic;
    
    {
        NSInteger localCounter = 42;
        __block char localCharacter;
    
        void (^aBlock)(void) = ^(void) {
            ++CounterGlobal;
            ++CounterStatic;
            CounterGlobal = localCounter; // localCounter fixed at block creation
            localCharacter = 'a'; // sets localCharacter in enclosing scope
        };
    
        ++localCounter; // unseen by the block
        localCharacter = 'b';
    
        aBlock(); // execute the block
        // localCharacter now 'a'
    }
    

    在此示例中, localCounter ,和 localCharacter 由于 localCharacter 存在,在块内部,只有对的修改 __block 。相反,块可以进行修改 localCharacter ,并且此修改在块外部可见。

  • aBlock 如何修改 localCounter?它似乎只修改 CounterGlobal。谢谢

  • 它不会修改 localCounter,但会修改 localCharacter。另外,请注意块中的 localCounter 值:它是 42,尽管变量在调用块之前但在创建块之后(即值被“捕获”时)增加了。

  • 这是一个很有帮助的解释 - 但是 - 你能解释一下你的解释中似乎相互矛盾的陈述吗?你在上面说“aBlock 修改了...localCounter”,然后在评论中说“[aBlock] 不会修改 localCounter。\”它是什么?如果它是“未修改”,那么你的答案应该被编辑吗?

  • wRAR 2月前 0 只看Ta
    引用 7

    一般情况下,没有 __block 的变量会在创建块时按值捕获并打包到块的“环境”中。但是 __block 变量不会被捕获,无论它们在块内还是块外使用,它们都会按原样被引用。

  • Lola 2月前 0 只看Ta
    引用 8

    博客文章 中深入介绍了块 ,并涉及__block 存储类型。

    __block 是一种独特的存储类型

    __block 和 static、auto 和 volatile 一样,是一种存储类型。它告诉编译器变量的存储需要以不同的方式进行管理。

    ...

    但是,对于 __block 变量,block 不会保留。您可以根据需要保留和释放。
    ...

    至于用例,你会发现 __block 它有时用于避免保留循环,因为它不保留参数。一个常见的例子是使用 self。

    //Now using myself inside a block will not 
    //retain the value therefore breaking a
    //possible retain cycle.
    __block id myself = self;
    
  • Mask 2月前 0 只看Ta
    引用 9

    有关保留周期问题的更多信息,请参阅此帖子:benscheirman.com/2012/01/…。 __weak 是否也适用于这种特定情况? 也许更清楚一点...

  • 引用 10

    最后,在 ARC 上下文中,声称 __block 可用于避免强引用循环(又称保留循环)是完全错误的。由于在 ARC 中 __block 会导致变量被强引用,因此它实际上更有可能导致这种情况。com/a/19228179/189006

  • 当您不使用 __block 时,块会复制变量(按值调用),因此即使您在其他地方修改变量,块也看不到更改。

    __block 使块保留对变量的引用(通过引用调用)。

    NSString* str = @"hello";
    void (^theBlock)() = ^void() {
        NSLog(@"%@", str);
    };
    str = @"how are you";
    theBlock(); //prints @"hello"
    

    在以下两种情况下你需要 __block:

    1. p3

      __block NSString* str = @"hello";void (^theBlock)() = ^void() {    str = @"how are you";};theBlock();NSLog(@"%@", str); //prints "how are you"
    2. p4

      __block NSString* str = @"hello";void (^theBlock)() = ^void() {    NSLog(@"%@", str);};str = @"how are you";theBlock(); //prints "how are you"
  • 我还要提到,标有 __block 的自动变量会被编译器转换为自动释放的对象,该对象的生命周期与块的生命周期一样长,甚至可能超出其声明的范围。此外,它每次都会被创建,因此创建的每个 theBlock 实例都会引用不同的 str 变量。

  • __block 是一个存储限定符,可以以两种方式使用:

    1. p1

    2. p2

    您可以参考 苹果文档 来了解详细信息。

  • 引用 14

    __block 是一种存储类型,用于使范围内的变量可变,更坦率地说,如果你用这个说明符声明一个变量,它的引用将被传递给块,而不是只读副本,有关更多详细信息,请参阅 iOS 中的块编程

  • 希望这对你有帮助

    假设我们有如下代码:

    {
         int stackVariable = 1;
    
         blockName = ^()
         {
          stackVariable++;
         }
    }
    

    它会给出一个错误,例如“变量不可分配”,因为块内的堆栈变量默认是不可变的。

    在声明前添加 __block(存储修饰符)使其在块内可变,即 __block int stackVariable=1;

  • 来自 块语言规范 :

    除了新的 Block 类型之外,我们还为局部变量引入了新的存储限定符 __block。[testme:块文字内的 __block 声明] __block 存储限定符与现有的局部存储限定符 auto、register 和 static 互斥。[testme] 由 __block 限定的变量就像它们位于分配的存储中一样,并且该存储会在最后一次使用该变量后自动恢复。实现可以选择一种优化,其中存储最初是自动的,并且仅在引用 Block 的 Block_copy 时才“移动”到分配的(堆)存储。此类变量可以像普通变量一样变异。

    如果 __block 变量是 Block,则必须假设 __block 变量驻留在分配的存储中,因此假设引用也位于分配的存储中的 Block(即它是 Block_copy 操作的结果)。尽管如此,如果实现为 Block 提供了初始自动存储,则没有规定执行 Block_copy 或 Block_release。这是由于可能存在多个线程试图更新共享变量的固有竞争条件,并且需要在处理旧值和复制新值时进行同步。这种同步超出了本语言规范的范围。

    有关 __block 变量应编译为的详细信息,请参阅 Block Implementation Spec ,第 2.3 节。

返回
作者最近主题: