Stefan Arn
Stefan Arn

Reputation: 1154

passing data between NSOperationQueue and mainQueue

I quite looked around to get an exact answer to this but was not able to find one.

In short: What's the best way to pass data from an operation queue to the main queue?

I have a heavy compute task that runs in an operation queue to compute an array. I would like to pass the results back to the main queue and use them there as a base for an UITableView.

The problem is that I'm not sure what's the best way to pass this data considering memory management. (The project does not use ARC). Is it safe to use autorelease on the operationQueueArray like this:

[operationQueue addOperationWithBlock:^{
    NSMutableArray *operationQueueArray = [[[NSMutableArray alloc] init] autorelease];

    // do some heavy compute and fill the results into the operationQueueArray

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // passing the data
        [mainQueueArray removeAllObjects];
        [mainQueueArray addObjectsFromArray:operationQueueArray];

        [myTableView reloadData];
    }];
}];

Is it guaranteed that the operationQueueArray is not released in the mainQueue with this code?

Or should I put some manual releases somewhere? Is there a better way or even a guideline how to do that?

Upvotes: 1

Views: 652

Answers (2)

Vlad
Vlad

Reputation: 3366

  [operationQueue addOperationWithBlock:^{
     NSMutableArray *operationQueueArray = [[[NSMutableArray alloc] init] autorelease];
     // do some heavy compute and fill the results into the operationQueueArray
     // If you log current thread here it should be a worker thread
     // do a sync call to your main thread with the computed data. Your async thread will not release its context, data, etc untill you finsihed passsing your data,
     // in other words, untill the dispatch_sync block does not finish
     dispatch_queue_t mainQueue = dispatch_get_main_queue();
     dispatch_sync(mainQueue, ^{
        // passing the data
        // If you do a log for [NSThread currentThread] here, it should be your main thread (UI thread)
        // It's safe to pass data to your table view as log as you retain your objects in your Table view controller data source array once you pass them there
        // and release them when your controller is released
        [mainQueueArray removeAllObjects];
        [mainQueueArray addObjectsFromArray:operationQueueArray];
        // Adding your objects to your main queue array will do +1 retain count to your objects.
        // They will only get released when your array is released.
        [myTableView reloadData];
     });
  }];

Upvotes: 1

Michał Ciuba
Michał Ciuba

Reputation: 7944

You are using operationQueueArray inside block passed to [[NSOperationQueue mainQueue] addOperationWithBlock:], so it will be retained (all objects referenced in a block are retained by it, unless you use __block specifier). So you don't have to worry about operationQueueArray being autoreleased in the other thread (the one used by operationQueue).

Upvotes: 1

Related Questions