magicalpanda / MagicalRecord

Super Awesome Easy Fetching for Core Data!
Other
10.8k stars 1.79k forks source link

NSFetchedResultsController request.fetchBatchSize ignored for defaultContext #1141

Open wiistriker opened 8 years ago

wiistriker commented 8 years ago

I have about 14k records in my database. I setup NSFRC with fetchBatchSize = 40

- (NSFetchedResultsController *)fetchedResultsController
{
    if (!_fetchedResultsController) {
        NSMutableArray *predicatesArray = [NSMutableArray array];

        NSPredicate *predicate;

        if (predicatesArray.count) {
            if (predicatesArray.count == 1) {
                predicate = [predicatesArray firstObject];
            } else {
                predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicatesArray];
            }
        }

        NSFetchRequest *request = [ProductEntity MR_requestAllSortedBy:@"createdAt,productId"
                                                             ascending:NO
                                                         withPredicate:predicate
                                                             inContext:self.managedObjectContext];

        [request setFetchBatchSize:40];

        NSFetchedResultsController *fetchedResultsController;
        fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                       managedObjectContext:self.managedObjectContext
                                                                         sectionNameKeyPath:nil
                                                                                  cacheName:nil];

        fetchedResultsController.delegate = self;
        _fetchedResultsController = fetchedResultsController;
    }

    return _fetchedResultsController;
}

If i use MR_defaultContext

- (NSManagedObjectContext *)managedObjectContext
{
    if (!_managedObjectContext) {
        _managedObjectContext = [NSManagedObjectContext MR_defaultContext];
    }

    return _managedObjectContext;
}

It seems CoreData load all my 14k in memory

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBARCODE, t0.ZCREATEDAT, t0.ZDESCRIPTIONSTRING, t0.ZDIRTY, t0.ZPARAMS, t0.ZPRESENCESTATUS, t0.ZPRICE, t0.ZPRODUCTDELETED, t0.ZPRODUCTID, t0.ZTITLE, t0.ZUPDATEDAT, t0.ZUSESTATUS, t0.ZTYPE FROM ZPRODUCTENTITY t0 ORDER BY t0.ZCREATEDAT DESC, t0.ZPRODUCTID DESC

My app freeze and memory usage is very high. There is no LIMIT 40 for sql query and when i scroll down the list no more new queries was sended to CoreData.

I investigate that if i use rootSavingContext

- (NSManagedObjectContext *)managedObjectContext
{
    if (!_managedObjectContext) {
        _managedObjectContext = [NSManagedObjectContext MR_rootSavingContext];
    }

    return _managedObjectContext;
}

Everything works very fast and more products loaded while scrolling. Memory usage is also very low.

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBARCODE, t0.ZCREATEDAT, t0.ZDESCRIPTIONSTRING, t0.ZDIRTY, t0.ZPARAMS, t0.ZPRESENCESTATUS, t0.ZPRICE, t0.ZPRODUCTDELETED, t0.ZPRODUCTID, t0.ZTITLE, t0.ZUPDATEDAT, t0.ZUSESTATUS, t0.ZTYPE FROM ZPRODUCTENTITY t0 WHERE  t0.Z_PK IN (SELECT * FROM _Z_intarray0)   LIMIT 40

But with rootSavingContext my tableview going crazy when model was changed. It seems delegate methods of NSFRC doesnt triggered.

Is i miss something? What should i do in this case?

wiistriker commented 8 years ago

When i use rootSavingContext NSFRC delegate methods called in background thread defaultContext NSFRC delegate methods called in mainThread.

So now i wrap all code in NSFetchedResultsController delegate methods with [[NSOperationQueue mainQueue] addOperationWithBlock and it seems it work just fine (for first look)

But it still feeling that i miss something and just doing it wrong for some reason

zarv1k commented 8 years ago

The issue is not related to MagicalRecord. There is a bug in Core Data. request.fetchBatchSize ignored when context used in NSFRC does not connected to PSC (context is child of parent context)