Search code examples
objective-cc++11lambdaobjective-c-blocksobjective-c++

How can I properly capture an Obj-C block within a c++ lambda call?


We recently ported our Obj-c application to be cross platform with c++. We are in the process of integrating it back into iOS and have to capture a block and NSObject into a lambda, and it makes me very nervous as I do not know if it will retain the memory correctly. Here is some test code

NSString* important_string = @"Test String";
void (^important_os_callback)(parameterTypes parameter);

my_cpp_function_with_lamdba([important_string, important_os_callback]()
{
    // Are the block and string still retained later?
    important_os_callback(important_string);
});

Solution

  • Yes, it will work correctly. A C++ lambda is equivalent to creating an unnamed struct type with the captured variables as fields. ARC ensures that when fields of a C++ struct have Objective-C object pointer type (or block pointer type), it will follow ARC semantics, i.e. the struct's constructor will initialize the field to nil; when someone assigns to the field, it releases the previous value and retains (or copies, if it's a block) the new value; and the struct's destructor will release the field.