the Reverend
the Reverend

Reputation: 12549

__block variables should be retained in a block

I want to use the results array after performing the block, my question is, should the results array instance be retained because it was originated from a block?

__block NSError *error = nil;    
__block NSArray *results;

[moc performBlockAndWait:^(void) {        
    results = [moc executeFetchRequest:fetchRequest error:&error]; 
    [results retain];
}];
if(results){
   //Do somehting
}

Upvotes: 3

Views: 1099

Answers (3)

bbum
bbum

Reputation: 162712

To be pedantically correct, you would do something like:

__block NSError *error = nil;    
__block NSArray *results;

[moc performBlockAndWait:^(void) {        
    results = [moc executeFetchRequest:fetchRequest error:&error]; 
    [results retain];
    if (!results) [error retain];
}];

if(results){
   //Do somehting
   [results release]; // or not -- assign it to something
} else {
   // Do something with error
   [error release]; // or autorelease
}

That is, you want a hard retain maintained from inside the block to outside the block always and regardless of synchronous execution. That retain must be balanced.

The over-arching rule is all about thread transfer; you are transferring objects from one thread of execution (wherever the block was executed) to the calling thread. There must be a hard retain across that transfer of ownership.

Upvotes: 2

Parag Bafna
Parag Bafna

Reputation: 22930

If you receive an autoreleased object, it will normally remain valid for the rest of the current method call and can even be returned as the result of the method. If you need to store it away for future use you must retain it.

Upvotes: 2

D.C.
D.C.

Reputation: 15588

I think this would fall into the general ownership rule for obj-c memory management. If you need that array, you should claim ownership by retaining it, and releasing it when you are done.

Upvotes: 3

Related Questions