【问题标题】:Are blocks passed by reference or by value from one call on stack to another?块是通过引用还是通过值从堆栈上的一个调用传递到另一个?
【发布时间】:2013-12-07 15:48:52
【问题描述】:

当我将块传递给其他方法时(不要用Block_copy@property(copy) 堆), 是复制还是引用传递?

我的意思是:

- (void)processBlock:(MyBlockType)block param:(int)param {

}

- (void)someMethod {
    int b1 = 10;
    int a1 = 9;
    [self processBlock:^int(int number, id object) {
        NSLog(@"block");
        return 1 + a1;
    } param:b1];
}

它是NSStackBlock - 因为它捕获“a”变量,所以它被分配在堆栈上。 当我将它们传递给另一个方法时,它是复制并存储在堆栈的processBlock's 部分,还是只是通过引用传递?

像这样:

copyOf myBlock
copyOf b1
processBlock
..........
..other variables..
a1
b1
myBlock
someMethod
..........

或者这样:

*myBlock (jast a pointer)
copyOf b1
processBlock
..........
..other variables..
a1
b1
myBlock
someMethod
..........

【问题讨论】:

  • 看到这个link
  • @Greg 但我没有找到我的问题的答案。该链接仅描述了在堆上传递块的情况以及弹出堆栈的情况。我会知道 myBlock 实例的复制方式是否与 b1 变量值的复制方式相同。对不起,如果我没有正确理解答案。谢谢。

标签: ios iphone objective-c objective-c-blocks


【解决方案1】:

首先,让我们澄清一些术语,因为这是造成混淆的根源。

如果我们真的很技术,你就不能“通过一个块”——你永远不能处理“一个块”。您只能操作“指向块的指针”。 something (^)() 类型是 pointer-to-block 类型。块字面量是块指针类型的表达式。函数Block_copyBlock_release 采用指针块类型。简而言之,你对块所做的一切都必须通过指向块的指针来完成。

在 Objective-C 中,块是对象。您将认识到 Objective-C 中的类似概念,即您永远无法直接处理“对象”。你只能处理指向对象的指针。

清除这些后,Objective-C 中的所有内容,就像在 C 中一样,都被传递并按值分配。没有“通过引用”。

在您展示的代码中,您通过值传递了一个指向块的指针。该指针指向一个块对象,是的,它位于堆栈帧上。如果有人在这个指针上调用了复制(并且从您的代码中不确定是否会发生这种情况,但假设确实发生了),那么复制函数将返回另一个指向堆中的新块对象的指针。

【讨论】:

    【解决方案2】:

    块是指针类型,指针是按值传递的。

    因此,在堆栈上创建并传递给函数/方法的块不会复制到被调用者的调用帧中。

    然而这并不意味着在使用 ARC 时可能没有预料到的某些情况下,该块可能不会被复制到堆中。堆栈块实际上是一种(内部)优化,由于它们被引入的方式而呈现给用户。您不应该依赖堆栈上的块。

    顺便说一句:“复制块”通常仅用于指代是否将块从堆栈复制到堆,这不是您要问的,因此您可能会从那条线上得到答案。

    【讨论】:

    • C 或 Objective-C 中没有通过引用传递。期间。
    • @newacct - 你是对的,我粗心大意并且使用了草率的语言。我应该知道得更好,并把它整理好。过失。
    猜你喜欢
    • 2020-04-01
    • 2012-10-11
    • 2015-04-10
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 2012-04-10
    • 2014-07-26
    • 2011-04-15
    相关资源
    最近更新 更多