当我将块传递给其他方法时(不是用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
..........
答案 0 :(得分:5)
首先,让我们澄清一些术语,因为这是混乱的根源。
如果我们真的技术性,你就不能“通过障碍” - 你永远不能处理“一块”。你只能操纵“指向块的指针”。类型something (^)()
是指针到块类型。块文字是指向块类型的表达式。函数Block_copy
和Block_release
采用指针到块的类型。简而言之,您使用块执行的所有操作都必须使用指向块的指针。
在Objective-C中,块是对象。您将认识到Objective-C中的类似概念,您永远不能直接处理“对象”。你只能处理指向对象的指针。
清除后, Objective-C中的所有内容(如C中)都会被传递并按值分配。没有“通过引用传递”。
在您显示的代码中,您将按值传递指向块的指针。该指针指向一个块对象,它是,驻留在堆栈帧上。如果有人在这个指针上调用copy(并且你的代码不确定会发生这种情况,但假设确实如此),那么copy函数将返回另一个指向新块对象的指针,该对象位于堆中。
答案 1 :(得分:4)
块是指针类型,指针是按值传递的。
因此,在堆栈上创建并传递给函数/方法的块不会被复制到被调用者的调用帧中。
然而并不意味着在使用ARC时您可能没有预料到的某些情况下可能无法将该块复制到堆中。堆栈块实际上是一种(内部)优化,由于它们的引入方式,它们浮现在用户身上。你不应该依赖堆栈中的块。
BTW:“复制一个块”通常只是用来指代块是否从堆栈复制到堆,这不是你要求的,所以你可能会得到这条线的答案。