Search code examples
c++objective-casynchronouslambdaobjective-c++

asynchronous request / response using lambda


I'm trying to figure out C++ syntax for a simple asynchronous request/callback pattern.

I have Objective-C code which looks like this:

NSString *arg0 = @"set.x"; // a string on the heap
NSArray *args = @[arg0];

[Request requestWithArgs:args onCompletion:^(NSDictionary *response, NSError *error)
{
    if(error)
    {
        // deal with it
    }
    else
    {
        id obj = response[arg0];
        // do things with the response
    }
}];

The request returns before the completionHandler, and the completionHandler block captures references to local variables (arg0). Behind the scenes, the Request class adds the provided anonymous completionHandler to a queue and calls it when the request has finished.

I figure in C++ lambdas are used? Just not sure about the syntax. And how do I keep or transfer ownership to passed variables so they are still around when the completionHandler is called? I figure any objects which are passed to the lambda need to be allocated on the heap if the objects should not be copied to it?

The response dictionary and error are created inside the request, and also need to be passed to the completionHandler. How do I do this correctly?

thanks!


Solution

  • Lambdas are closures. Any variable that is in scope when the lambda is created can be captured, either by value or by reference. I'm not an Objective-C programmer, but I'd guess that a rough equivalent to your function in C++ would look something like this:

      auto onCompletion = [&arg0](NSDictionary *response, NSError *error) { 
         // function body goes here
      }
    

    That code defines a function object which captures arg0 by reference, takes two parameters, and returns nothing. It assigns that function object to a variable called OnCompletion.

    Capturing by reference does require that the captured variable will have a lifetime at least as long as the lambda-generated function object. If that's not the case, then omit the & before arg0 and it will be captured by value instead.

    If you need to define a lambda with a return value, the return type is defined after the parameter list, preceded by the arrow operator. Here's what the lambda above would look like if it defined a function returning an int:

      auto onCompletion = [&arg0](NSDictionary *response, NSError *error) -> int { 
         // function body goes here
      }