0

I have entity1 which contains NSOrderedSet of entity2. Entity2 has 100 string fields.

I create managedObject of entity2 per/sec during 2-3 hours and add it to entity1. I can create some entity1 per/day. I do it everyday! I can't create them rarely (It is required).

So in one week my CoreDate dataBase will contain (7 * 3 or 4) 21 or 28 managedObjects of entity1 which contains (21 * 2 or 3 * 3600) 226800 objects of entity2.

And each next operation (insert, remove, save) with coreData will go more slowly than before.

How can I resolve this problem?

Gavilan Comun
  • 1,361
  • 2
  • 11
  • 19
gaRik
  • 607
  • 6
  • 10

2 Answers2

2

So your app is going to take up more and more of the user's storage forever? Sounds like a good way to get deleted.

If you're dealing with lots of data and want fast query results so that your app is responsive, you should use concurrency with Core Data so the actual data work is done on another thread, and once everything is loaded you can update your UI. The modern way to do that is a combination of creating MOCs with a Concurrency Type and using parent/child contexts, or using the new asynchronous fetching introduced in iOS 8.

bpapa
  • 21,409
  • 25
  • 99
  • 147
  • https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html – boidkan Apr 16 '15 at 21:03
1

In addition to the other respondents I provide the following advice...

Create two contexts during the construction of your core data stack and using:

  • NSPrivateQueueConcurrencyType,
  • NSMainQueueConcurrencyType.

Know that you'll need to hook up your NSPersistentStoreCoordinator to the NSPrivateQueueConcurrencyType.

and [UPDATE]

Make the MOC of NSPrivateQueueConcurrencyType the parent of the NSMainQueueConcurrencyType.

I've prepared my Core Data solutions based a lot on what I've learned from reading Marcus Zarra's book, from The Pragmatic Bookshelf – "Core Data, 2nd Edition, Data Storage and Management for iOS, OS X, and iCloud" (Jan 2013) in particular the chapters on (4) Performance Tuning and (5) Threading.

For a more up to date and all encompassing solution that I have not yet implemented, read this article My Core Data Stack by Zarra.

My solution involves writing a custom save method built alongside (in the same class as) my core data stack, shown following. Note that the save method is called at appropriate points in code.

Using this mechanism, constant and regular saves are persisted to memory (fast) in the main queue, and saves to the database are persisted to disk (slow) in a private queue.

Maybe this is a suitable path for you to consider - it works very well for me?

Properties...

@property (nonatomic, strong) NSManagedObjectContext *mocPrivate;
@property (nonatomic, strong) NSManagedObjectContext *mocMain;

Custom save method...

- (void)saveContextAndWait:(BOOL)wait {
    if ([self.mocMain hasChanges]) {
        [self.mocMain performBlockAndWait:^{
            NSError __autoreleasing *error;
            BOOL success;
            if (!(success = [self.mocMain save:&error]))
                NSLog(@"%@ - %@ - CORE DATA - E~R~R~O~R saving managedObjectContext MAIN: %@, %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), error.localizedDescription, error.localizedFailureReason);
            NSLog(@"%@ - %@ - CORE DATA - Success saving managedObjectContext MAIN?: %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), success ? @"YES_" : @"NO_");
        }];
    }

    void (^savePrivate) (void) = ^{
        NSError __autoreleasing *error;
        BOOL success;
        if (!(success = [self.mocPrivate save:&error]))
            NSLog(@"%@ - %@ - CORE DATA - E~R~R~O~R saving managedObjectContext PRIVATE: %@, %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), error.localizedDescription, error.localizedFailureReason);
        NSLog(@"%@ - %@ - CORE DATA - Success saving managedObjectContext PRIVATE?: %@", NSStringFromClass(self.class), NSStringFromSelector(_cmd), success ? @"YES_" : @"NO_");
    };

    if ([self.mocPrivate hasChanges]) {
        if (wait) {
            [self.mocPrivate performBlockAndWait:savePrivate];
        } else {
            [self.mocPrivate performBlock:savePrivate];
        }
    }
}
andrewbuilder
  • 3,629
  • 2
  • 24
  • 46