RestKit, Core Data, Magical Record, Lots of data a

2019-08-26 02:57发布

问题:

I got an app which stores data about restaurants. Their menu, schedule and so on. Theres ~200 restaurants in the DB by now. The app used to retrieve those places by a single shot, but it was taking too much time to load, so i decided to load the data one by one. On the start app asks the server for an array of place's ids, then get the data via API.

I set completion blocks for RK's operations to background queues, but it didn't help. Scrolls are running not smoothy enough and sometimes the app even deadlocks(sic!) or crashes with no error output in the console. I've tried using Instruments to locate what makes UI go jerky, but didn't succeed. I even turned off image loading and sorting functions. I used to have RK's requests calls wrapped in @synchronized, so i removed it, but no effect.

Never thought i'd be facing this kind of issue after few weeks of experience with objective-c. I've tried every possible way that came to my mind, so now im kinda giving up.

Please help me :)

The code below gets called 200 times right after the app start.

NSURLRequest *request = [[DEAPIService sharedInstance].manager requestWithObject:nil
                                                                              method:RKRequestMethodGET
                                                                                path:path
                                                                          parameters:params];
    //DLog(request.URL.absoluteString);

    NSManagedObjectContext *context = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_contextForCurrentThread]];

    RKManagedObjectRequestOperation *operation = [[DEAPIService sharedInstance].manager managedObjectRequestOperationWithRequest:request
                                                                                                        managedObjectContext:context
                                                                                                                         success:success
                                                                                                                         failure:failure];

    // dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.name.bgqueue", NULL);
    operation.successCallbackQueue = backgroundQueue;

    [[DEAPIService sharedInstance].manager enqueueObjectRequestOperation:operation];

Response descriptors are set before that. And also there's many relations in the DB. I've looked up the DB's file size - it's ~1.5Mb. I wonder what will happen if there would be over 1k restaurants. Is it a good way to load this kind of data? What are the best practises?

回答1:

Ok, from the information provided you should be able to simplify a lot. At the moment your code is dropping down to a low level and getting involved in threading and context management that you want to leave for RestKit to sort out. You have a properly configured object manager and core data stack by the looks of things so you should let it do the work.

This means removing the request, context and request operation code and simply calling `getObjectsAtPath:parameters:success:failure:'. RestKit will then deal with all of the download and mapping in the background and save the context.

You should also really be using fetched results controllers throughout your app, and if you are they will automatically detect the changes that RestKit has saved and update your UI.

Once you have that, any blocking of the UI is unrelated to RestKit and your download requirement and should be related to subsequent image management / downloads.