Search code examples
iosobjective-crealm

Fast enumeration with RLMResults on large datasets


I'm running into an issue where I need to enumerate an RLMResults collection on a relatively large data set (>7,000 items). I get that realm lazily loads its objects as they are accessed, but the issue I run into is that I need to access each of these items in the collection which causes each of the 7,000+ items to be loaded into memory thereby causing an out of memory error. According to the realm documentation they don't support limiting the results of a query.

An example of something I might need to do is to go through and delete files from the file system, and yes I could query using a predicate and only ask for items that are cached, but in a worst case scenario that query could return all items in the library.

RLMResults<DLLibrary *> *allItems = [DLLibrary allObjects];
for( DLLibrary *item in allItems ) {
  // My understanding is that once the realm object is ready, it will be
  // lazily loaded into memory. If I have many 1,000's of items in my data
  // store this quickly becomes a problem memory wise.
  if( item.isCached ) {
    [[DLCacheService instance] deleteCachedFileWithDocumentId:item.id];
  }
}

Solution

  • The easiest way to mitigate this would be the use of an @autoreleasepool brace to explicitly guarantee the object you lazily-loaded is promptly released once you've finished checking its contents. :)

    RLMResults<DLLibrary *> *allItems = [DLLibrary allObjects];
    for (NSInteger i = 0; i < allItems.count; i++) {
        @autoreleasepool {
            DLLibrary *item = allItems[i]; 
            if (item.isCached) {
                [[DLCacheService instance] deleteCachedFileWithDocumentId:item.id];
            }
        }
    }