Travis Beech Travis Beech -4 years ago 122
iOS Question

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];
}
}

Answer Source

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];
        }
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download