Core Data: Memory not released after manually faulting managed objects

孤人 提交于 2020-01-03 01:22:45

问题


I am using the following code to retrieve the maximum value of an attribute on Core Data

- (NSDate*)latestDateForLocalEntity:(NSString*)entityString
   key:(NSString*)key 
   inManagedObjectContext:(NSManagedObjectContext*)context {

   NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityString];
   NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:YES];
   request.sortDescriptors = @[sortDescriptor];
   NSError *localError;
   NSArray *localResults = [context executeFetchRequest:request error:&localError];
   id result = localResults.lastObject;

   NSDate *latestLocalDate = [result valueForKey:key];
   NSLog(@"Latest local date for entity %@ (%@): %@",entityString,key,latestLocalDate);

   // fault newly created objects - don`t need to keep them in RAM:
   [localResults enumerateObjectsUsingBlock:^(NSManagedObject *managedObject, NSUInteger idx, BOOL *stop) {
      [context refreshObject:managedObject mergeChanges:NO];
   }];

   // even context reset does not help reducing RAM consumption:

  [context reset];
  localResults = nil;
  return latestLocalDate;

The code retrieves all entities, sorts them by value and takes the last object to get the maximum value. It then tries to (re)fault the values in order to release RAM: [context refreshObject:managedObject mergeChanges:NO].

However, memory seems not being released (roughly 400.000 non-objectobjects are kept in memory).

What is wrong with my code trying to refault the objects and resetting the managed object context? Why does it not release memory?


回答1:


If you are only interested in the maximum value of one attribute, I would suggest that you fetch only one object with

// Sort descending to that the first object is that with the maximum value.
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:NO];
[request setSortDescriptors:@[sortDescriptor]];
[request setFetchLimit:1];

Then only one object is loaded into memory instead of all objects of that entity.

In addition, you can fetch only the attribute that you are interested in instead of the managed object:

[request setResultType:NSDictionaryResultType];
[request setPropertiesToFetch:@[key]];

Then the result is an array of dictionaries and no managed objects are loaded at all into the context. One caveat here is that the result reflects the current state in the persistent store, and does not take into account any pending changes, insertions, or deletions in the context.



来源:https://stackoverflow.com/questions/18394989/core-data-memory-not-released-after-manually-faulting-managed-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!