在ARC ObjectiveC++中使用C++ 11 lambda函数 - 如何正确地完成它?

Lar*_*der 8 lambda objective-c objective-c-blocks automatic-ref-counting c++11

我有一个ObjectiveC++项目.在ObjectiveC上下文中,我使用ARC和iPhoneSDK 6.在C++中,我使用的是C++ 11编译器.

C++ 11中的Lambda函数正在使用引用捕获变量.ObjectiveC并没有真正支持这个概念,"尝试和错误"我提出了以下解决方案.我不知道有任何陷阱吗?

这个问题有更好的解决方案吗?

typedef std::function<void ()> MyLambdaType;

...
// m_myView will not go away. ARC managed.
UIView * __strong m_myView;

...
// In Objective C context I create a lambda function that calls my Objective C object
UIView &myViewReference = *m_myView;
MyLambdaType myLambda = [&myViewReference]() {
    UIView *myViewBlockScope = &myViewReference;
    // Do something with `myViewBlockScope`
}

..
// In C++11 context I call this lambda function
myLambda();
Run Code Online (Sandbox Code Playgroud)

new*_*cct 14

直截了当的做法是让lambda捕获对象指针变量m_myView(我假设你的代码片段是一个局部变量),并在lambda中正常使用它:

MyLambdaType myLambda = [m_myView]() {
    // Do something with `m_myView`
}
Run Code Online (Sandbox Code Playgroud)

唯一的问题是内存管理m_myView.一般来说,lambda m_myView在创建时需要保留,并在它被销毁时释放它(就像块一样;因为lambda可以在m_myView不存在的范围内使用).

通过ARC文档阅读,我没有看到具体提到的这种情况,但我认为它应该正确处理它,因为(1)C++ 11 lambda的捕获变量存储为匿名类的字段,这些是在构造lambda时初始化为捕获的值,以及(2)ARC在构造和销毁时正确处理C++类的Objective-C对象字段的保留和释放.除非它相反地说明了关于lambdas的内容,或者存在编译器错误,否则我认为它没有理由不起作用.

  • 这绝对有效.棘手的是,在C++ 11 lambda术语中,`m_myView`在这里被"按值"捕获.如果你"通过引用"捕获它(如:`[&m_myView](){...}`)对象`m_myView`由ARC保留*NOT*.如果你考虑一下,这是完全合理的(即当你告诉C++通过引用捕获`m_myView`时,C++正在捕获指针*的引用*,而不是对象的引用)但是术语可能有点令人困惑. (4认同)