Objective-C block如何捕获非对象值?

Objective-C block如何捕获非对象值?,objective-c,Objective C,这是苹果官方指南中的一个例子 现在,对于对象值,很容易理解,它保留了对它的引用。所以后来,当它的原始引用更改为指向其他对象时,或者只是被销毁。此引用仍然存在,因此引用计数不会为零,并且保留原始值 但是,对于上面的示例代码,它不是一个对象。块保留对它的引用,然后值更改为84。我认为这是对自身的更改,而不是对其副本的更改,这意味着指针指向的值已更改。它怎么可能仍然是42?块引入了必要的间接寻址,以确保发生这种情况。看起来是本地的但被块捕获的变量实际上是由编译器在堆上分配的。除其他事项外,这对于该变量

这是苹果官方指南中的一个例子

现在,对于对象值,很容易理解,它保留了对它的引用。所以后来,当它的原始引用更改为指向其他对象时,或者只是被销毁。此引用仍然存在,因此引用计数不会为零,并且保留原始值


但是,对于上面的示例代码,它不是一个对象。块保留对它的引用,然后值更改为84。我认为这是对自身的更改,而不是对其副本的更改,这意味着指针指向的值已更改。它怎么可能仍然是42?

块引入了必要的间接寻址,以确保发生这种情况。看起来是本地的但被块捕获的变量实际上是由编译器在堆上分配的。除其他事项外,这对于该变量能够超过其在中声明的函数的生存期是必要的。

块引入了必要的间接方法,以确保发生这种情况。看起来是本地的但被块捕获的变量实际上是由编译器在堆上分配的。除其他事项外,该变量必须能够超过其声明的函数的生命周期。

来自文档部分:

以下规则适用于块内使用的变量:

  • 全局变量是可访问的,包括存在于封闭词法范围内的静态变量
  • 传递给块的参数是可访问的(就像函数的参数一样)
  • 封装词法作用域的局部堆栈(非静态)变量被捕获为常量变量。 它们的值在程序中的块表达式点处获取。在嵌套块中,从最近的封闭范围捕获值
  • 使用_块存储修饰符声明的封闭词法范围的局部变量由引用提供,因此是可变的。 任何更改都会反映在封闭词法范围中,包括在同一封闭词法范围内定义的任何其他块。这些将在_块存储类型中进行更详细的讨论
  • 在块的词法范围内声明的局部变量,其行为与函数中的局部变量完全相同。 块的每次调用都提供该变量的新副本。这些变量可以依次用作常量或块中包含的块中的引用变量
  • 规则3适用于您问题中的代码。

    来自文档部分:

    以下规则适用于块内使用的变量:

  • 全局变量是可访问的,包括存在于封闭词法范围内的静态变量
  • 传递给块的参数是可访问的(就像函数的参数一样)
  • 封装词法作用域的局部堆栈(非静态)变量被捕获为常量变量。 它们的值在程序中的块表达式点处获取。在嵌套块中,从最近的封闭范围捕获值
  • 使用_块存储修饰符声明的封闭词法范围的局部变量由引用提供,因此是可变的。 任何更改都会反映在封闭词法范围中,包括在同一封闭词法范围内定义的任何其他块。这些将在_块存储类型中进行更详细的讨论
  • 在块的词法范围内声明的局部变量,其行为与函数中的局部变量完全相同。 块的每次调用都提供该变量的新副本。这些变量可以依次用作常量或块中包含的块中的引用变量

  • 规则3适用于问题中的代码。

    长话短说:复制整数值。(更准确地说:结构和对象引用也会被复制。但对于对象引用,它是一个引用。)


    顺便说一句:这就是闭包的意思。这就是为什么要关闭。他们存在的原因。你想要的正是这种行为。否则,您必须确保在块运行时(可能是几秒钟或几分钟后)不会更改值。

    长话短说:复制整数值。(更准确地说:结构和对象引用也会被复制。但对于对象引用,它是一个引用。)


    顺便说一句:这就是闭包的意思。这就是为什么要关闭。他们存在的原因。你想要的正是这种行为。否则,您必须确保在块运行时(可能是几秒钟或几分钟后)不会更改值。

    这不是原因,编译器会检测块是否可以保留捕获变量的范围。复制的原因(可以保存在堆栈或堆上)是,这是闭包的含义。这不是原因,编译器会检测块是否可以保留捕获变量的范围。复制(可以在堆栈或堆上保存)的原因是,这就是闭包的含义。
    int anInteger = 42;
    
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
    
    anInteger = 84;
    
    testBlock();
    
    Integer is: 42