块是通过引用还是通过值从堆栈上的一个调用传递到另一个?

时间:2013-12-07 15:48:52

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

当我将块传递给其他方法时(不是用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
..........

2 个答案:

答案 0 :(得分:5)

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

如果我们真的技术性,你就不能“通过障碍” - 你永远不能处理“一块”。你只能操纵“指向块的指针”。类型something (^)()指针到块类型。块文字是指向块类型的表达式。函数Block_copyBlock_release采用指针到块的类型。简而言之,您使用块执行的所有操作都必须使用指向块的指针。

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

清除后, Objective-C中的所有内容(如C中)都会被传递并按值分配。没有“通过引用传递”。

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

答案 1 :(得分:4)

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

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

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

BTW:“复制一个块”通常只是用来指代块是否从堆栈复制到堆,这不是你要求的,所以你可能会得到这条线的答案。