核心数据使用完成处理程序执行获取请求或在主线程以外的某些其他线程中执行

时间:2017-04-03 09:48:17

标签: ios objective-c multithreading core-data nsincrementalstore

在我的iOS应用程序中,我正在使用Core Data。 对于表View列表,我使用NSFetchedResultsController和 连接到远程存储我使用NSIncrementalStore。

我的FetchedResultsController上下文有MainQueue Cuncurrency类型。(我无法使用PrivateQueueCurrencyTYpe)。

为了解决Fault,对于许多关系,从我的IncrementalStore子类执行executeFetchResultsCall:withContext:error方法。

在executeFetchResults方法中,如果我的本地数据库中没有API,我将调用API(连接到远程服务器)。

myarray = [object representationsForRelationship:@" manyconnection" withParams:无];

现在我需要同步返回结果数组以返回到ExecuteFetchResultsMethod。此操作也应在主线程上执行。

所以我只有一个选项来从服务器获取结果,导致UI在指定的休眠时间内无响应。

return

当在主线程上执行上述操作时,UI挂起。

为了使UI更流畅,我需要在其他一些不可能的线程中执行executeFetchrequest。

它还期望返回结果数组。

有没有选择以完成处理程序的方式执行此类操作?

任何替代方法或设计都可以正常使用。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

这是一个骨架,使用dispatch_group,假设您使用NSFetchedResultsController来更新UITableView

@implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        // do your setup (FetchedResultsController and such)
        [self syncData];
    }

    - (void)syncData
    {
        NSArray<Entity*> *results = [self fetchData];
        BOOL needsUpdateFromServer = YES; // check your results and set this bool accordingly

        if (!needsUpdateFromServer) {
            return;
        }

        __block ServerResponse *fromServer = nil;
        __block dispatch_group_t group = dispatch_group_create();
        dispatch_group_enter(group);
        [self loadDataFromServer:^(ServerResponse *response) {
            fromServer = response;
            dispatch_group_leave(group);
        }];

        dispatch_group_notify(group,dispatch_get_main_queue(),^{
            [self persistData:fromServer];
            /*
             According to our discussion, you are using an NSFetchedResultsController. 
             So your tableView should update automatically after persisting the data.
             */
        }); 
    }

    - (void)loadDataFromServer:(void (^)(ServerResponse *response))completion
    {
        // [someDownloadService downloadDataFromServerInBackgroundWithCompletion:^(ServerResponse* response){
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(response);
            });
        // }];
    }

    - (NSArray<Entity*>*)fetchData
    {
        NSArray<Entity*> *results = nil;
        // fetch from core data and return it
        return results;
    }

    - (void)persistData:(NSArray<ServerResponse*> *)serverResponses
    {
        // parse whatever you get from server
        // ... and persist it using Core Data
    }

@end