0

I parse the content of a file in order to create a set of NSManagedObject in a context and save them. This is the method where I do this:

- (BOOL)getEntitiesFromFileInContext:(NSManagedObjectContext *)context
{
   BOOL result = YES;
   NSMutableArray *entities = [[NSMutableArray alloc] init];

   NSString *entitiesFileContent = [FilesManagerHelper readFile:fileName];

   if ([entitiesFileContent isEqualToString:@""]) {
       result = NO;
   }
   else {
       @autoreleasepool {
           entities = [self parseEntitiesFileContent:entitiesFileContent inContext:context];

           // If entities.count > 0, some operations here
       }

       // Save context and reset
       [self saveContext:context];
       [self clearContext:context];
   }

   return result;
}

In parseEntitiesFileContent:inContext: method I insert the NSManagedObject objects in the context I provide and I also add them to the entities array.

I'm performing this in an @autoreleasepool because I found an example doing that, but I'm not sure if it is really necessary... Could somebody explain me what the difference between using @autoreleasepool and not using it should be?

Thanks so much

EDIT: Should the entities array be defined inside the @autoreleasepool block?

AppsDev
  • 12,319
  • 23
  • 93
  • 186
  • I would expect a static analyser warning that says 'entities is never read'. Am I missing something - What is 'entities' purpose within the scope of this method? – Bamsworld Sep 26 '15 at 11:38
  • @Bamsworld You're right, I missed some code there. Edited the code snippet. – AppsDev Sep 26 '15 at 12:12

2 Answers2

0

The @autorelase statement implies creation of an autorelease pool that will contain all the objects that are marked as autorelease withing the scope of @autorelease{}. Thus, using @autorelease make sense if and only if there's a relatively considerable amount of autorelease-marked objects (it's needed not only of just-in-time memory deallocation but for avoiding "memory peaks" as well). Memory allocation and deallocation is a large topic to be explained in a single post, but the main rule is: use @autorelease for a scope if it's going to contain plenty of autorelease-marked objects.

Arthur Gevorkyan
  • 2,069
  • 1
  • 18
  • 31
  • Thanks, so... I'd use `@autorelease` only if I expect to get a very large file with objects to be parsed? The problem is that I don`t know beforehand how many objects I will have in such file. Would it be better to keep the ´@autorelease´ block just in case? – AppsDev Sep 26 '15 at 12:18
  • The answer to your questions is: "nor exactly". About the large amount of data: if you use 1 instance of NSData, it'll be either released (when you cease to use it) or retained by a strong reference if you assing the data to one. Keeping the @autorelease scope for no reason is an overkill. It all depends on how many "autorelease-marked" objects you use and on what you plan to do with those objects at the scope end. There's already a rich discussion on StackOverflow: http://stackoverflow.com/questions/9086913/objective-c-why-is-autorelease-autoreleasepool-still-needed-with-arc. Hope it'll help. – Arthur Gevorkyan Sep 26 '15 at 13:26
  • Thanks so much for the explanation – AppsDev Sep 26 '15 at 14:15
0

Because entities is declared within the scope of the method but not in the autorelease pool block, you have a strong pointer to entities outside the autorelease pool block and the auto release pool in this case will have no effect.

To verify this try logging entities just before the method returns.

For the auto release pool block to have some meaning, declare entities within the auto release pool block.

@autoreleasepool {
       NSMutableArray *entities = [self parseEntitiesFileContent:entitiesFileContent inContext:context];

       // If entities.count > 0, some operations here
   }

Now try and log entities straight after the auto release pool block.

This case is rather trivial if entities is small, however it is not a bad to include as it may help with scalability as this method may evolve over time and the auto release block starts to do more. If entities can be potentially large then you most definitely want the pool. My advice is to leave the auto release pool block and move the declaration of entities inside the pool block.

Bamsworld
  • 5,670
  • 2
  • 32
  • 37