malaba
malaba

Reputation: 654

Memory management with block and ARC, leak?

I need to know if I do it correctly. The application is running OK but I'm not sure I get the lifecycle correctly (leak ?).

Note: Instrument see no leak.

The code of a method aaa: of some class A:

- (void) aaa {
   NSString *path = ...something...;

   NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
   // using path
   [self somethingElseWith:path];
   }];

   [self.aQueue addOperation:theOp];
}

So I create a block to put on aQueue (NSOperationQueue*). The goal is to offload from the main thread the long running somethingElseWith: method, so that the GUI continue to be responsive.

Inside the block I reference the local var "path" that will be out of scope at the end of the aaa: method.

If I read the doc correctly, the block will do a retain on 'path'. But is ARC inserting a release at the end of this block implicitly ? Would be logical and nice.

Or should I declare 'path' as __block and assign it to nil at the end of my block ? (manual...)

Not sure I understand how to use __weak in this context.

Upvotes: 2

Views: 1892

Answers (2)

Joe
Joe

Reputation: 57169

The path variable is fine. You may however need to avoid a retain cycle by using a weak reference to self. If aQueue is a strong reference there may be a retain cycle causing self never to be released.

Solution:

- (void) aaa {
   NSString *path = ...something...;

   __weak id self_ = self;
   NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
   // using path
   [self_ somethingElseWith:path];
   }];

   [self.aQueue addOperation:theOp];
}

Make sure the operation does not get called after the class should no longer exist.

Upvotes: 6

Art Gillespie
Art Gillespie

Reputation: 8757

The block will automatically handle memory management for any locals from the enclosing scope. You don't have to worry about retain/release pairs in this case. Note, though that path will be const within the block's scope. If you need pathto be mutable within the block, use the __block attribute.

The different ways a block handles variables is described in detail here: Blocks and Variables

Upvotes: 3

Related Questions