在Objective-C中,我们知道块在运行时有3个实现。
NSGlobalBlock
- 在运行时是单例,并且在我们不使用堆栈变量值的情况下创建它。NSStackBlock
- 这不是单例,它是在堆栈上分配的(不在堆上),它是在我们使用一些堆栈变量时创建的。NSMallocBlock
- 在堆上分配,当我们想要将块存储为某些类的ivar或属性或堆f.e中的任何位置时使用。 @property (nonatomic, copy) MyBlockType myBlock;
或我们使用Block_copy()
函数时。这非常重要,因为NSMallocBlock保留了来自上下文的对象,如果我们不使用正确的块,这个事实可以创建一些拥有周期。所以,我的问题是:“我在哪里可以找到C ++ lambdas运行时的完整解释,以及它们如何被Compiler处理?或者你可以解释一下吗?使用C ++ lambdas进行内存管理是否有任何特定问题?lambdas是什么?在堆上或堆栈上分配?“
答案 0 :(得分:2)
Lambdas实现是特定于编译器的。
标准没有指定内存分配的位置,但作为经验法则,它们大致相当于old-school functors ,并且它们及其捕获的值被复制到堆栈,就像任何普通对象一样。
E.g。
std::vector<int> v{10,11,12,13};
std::for_each(v.begin(), v.end(), [](int& i) {i++;});
只是一种无国籍的功能。
或者,
std::vector<int> v{10,11,12,13};
int C = 10;
int D = 20;
std::for_each(v.begin(), v.end(), [C,&D](int& i) {i += C + D;});
等同于在堆栈上构建的仿函数,其副本为C
,并且D
作为其成员的引用(但可能会被优化掉)。
你真正将一个lambda对象放在堆上的唯一一次是它转换为std::function
时,它的完成方式取决于编译器对std::function
的实现。
void g(const std::function& f);
// ...
auto f = [=](int& i){i += C;}; // still on the stack (compiler-specific type)
g(f); // std::function constructed, possibly on the heap