MagicalRecord 在导入时保存所有内容之前完成块 [英] MagicalRecord finish block before everything is saved on import

查看:33
本文介绍了MagicalRecord 在导入时保存所有内容之前完成块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当有人登录我的应用程序时,会发出一个带有 JSON 响应的调用,我使用此数据通过 MagicalRecord 将其导入到 Core Data 中.在所有导入完成后,调用一个名为 success 的块,让我的 LoginViewController 知道一切正常,并停止 UIActivityIndi​​catorView,以便它可以进行 segue.

When someone logins my app, a call with a JSON response is made, and I use this data to import it into Core Data with MagicalRecord. After all importing is done, a block named success is called to let my LoginViewController know everything was fine, and stopping the UIActivityIndicatorView, so it can make a segue.

它转到一个新的 ViewController 并且它有一个 UITableView 来显示新导入的数据.

It Segue to a new ViewController and it has a UITableView to display the freshly imported data.

我的问题是,这个成功块在之前MagicalRecord 被调用.因此 UITableView 还没有收到要显示的 Orders 对象.

My problem is, that this success block is been called before MagicalRecord is done with the savings. Therefor the UITableView has not received the Orders objects to display yet.

这是我对 saveWithBlockAndWait 块的实现如下:

Here's my implementation of saveWithBlockAndWait block is as following:

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {

    NSDictionary *users = [responseObject valueForKeyPath:@"responses.user"];
    [User importFromObject:users inContext:localContext];

    NSArray *orders = [responseObject valueForKeyPath:@"responses.orders"];
    [Order importFromArray:orders inContext:localContext];    

    NSLog(@"SAVING DONE");
}];

在我的 OrdersViewController(女巫是 ViewController 也有转场)是另一个 NSLog,问题可能就在这里.

In my OrdersViewController (witch is the ViewController there's been segue too) is another NSLog, and it's here the problem might be.

Xcode 的输出显示 SAVING DONE 被调用,但在我的 AFNetworking 调用之后.这意味着所有数据都没有保存,也没有准备好显示 - 即使使用 saveWithBlockAndWait.输出还显示有 0 行.

The output from Xcode shows that SAVING DONE is been called, but right after my AFNetworking calls. That means all the data is not saved, and not ready to display - even with the saveWithBlockAndWait. Also the output shows that there's 0 rows.

该应用在我第二次发布时运行良好.只有在第一次登录时我才遇到这个问题

The app works perfect on my second launch. It's only on the first login I have this problem

2015-05-04 19:16:31.617 xxxxx[35555:5569667] +[NSManagedObjectContext(MagicalRecord) MR_contextWithStoreCoordinator:](0xff4a04) -> Created Context UNNAMED
2015-05-04 19:16:31.618 xxxxx[35555:5569667] +[NSManagedObjectContext(MagicalRecord) MR_setRootSavingContext:](0xff4a04) Set Root Saving Context: <NSManagedObjectContext: 0x7aecdf10>
2015-05-04 19:16:31.618 xxxxx[35555:5569667] +[NSManagedObjectContext(MagicalRecord) MR_newMainQueueContext](0xff4a04) Created Main Queue Context: <NSManagedObjectContext: 0x7aff4280>
2015-05-04 19:16:31.618 xxxxx[35555:5569667] +[NSManagedObjectContext(MagicalRecord) MR_setDefaultContext:](0xff4a04) Set Default Context: <NSManagedObjectContext: 0x7aff4280>
2015-05-04 19:16:46.104 xxxxx[35555:5569667] POST 'secret'
2015-05-04 19:16:47.237 xxxxx[35555:5569667] 200 'secret' [1.1324 s]
2015-05-04 19:16:47.258 xxxxx[35555:5569667] POST 'secret'
2015-05-04 19:16:47.880 xxxxx[35555:5569667] 200 'secret' [0.6215 s]
2015-05-04 19:16:47.901 xxxxx[35555:5569667] SAVING DONE
2015-05-04 19:16:47.902 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ae251e0) → Saving <NSManagedObjectContext (0x7ae251e0): *** UNNAMED ***> on *** MAIN THREAD ***
2015-05-04 19:16:47.903 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ae251e0) → Save Parents? 1
2015-05-04 19:16:47.903 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ae251e0) → Save Synchronously? 1
2015-05-04 19:16:47.903 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7ae251e0) Context UNNAMED is about to save. Obtaining permanent IDs for new 2 inserted objects
2015-05-04 19:16:47.906 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7aecdf10) → Saving <NSManagedObjectContext (0x7aecdf10): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
2015-05-04 19:16:47.906 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7aecdf10) → Save Parents? 1
2015-05-04 19:16:47.906 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7aecdf10) → Save Synchronously? 1
2015-05-04 19:16:47.907 xxxxx[35555:5569667] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7aecdf10) Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 2 inserted objects
2015-05-04 19:16:47.909 xxxxx[35555:5569667] __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke21(0x7aecdf10) → Finished saving: <NSManagedObjectContext (0x7aecdf10): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
2015-05-04 19:16:47.909 xxxxx[35555:5569667] All data has been setup sucessfully
2015-05-04 19:16:47.909 xxxxx[35555:5569667] Perform Segue To LoginSucessSegue from LoginViewController
2015-05-04 19:16:47.945 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ae19130) → Saving <NSManagedObjectContext (0x7ae19130): *** UNNAMED ***> on *** BACKGROUND THREAD ***
2015-05-04 19:16:47.952 xxxxx[35555:5569667] Number of rows: 0
2015-05-04 19:16:47.957 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ae19130) → Save Parents? 1
2015-05-04 19:16:47.957 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7ae19130) → Save Synchronously? 0
2015-05-04 19:16:47.958 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7ae19130) Context UNNAMED is about to save. Obtaining permanent IDs for new 4 inserted objects
2015-05-04 19:16:47.962 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7aecdf10) → Saving <NSManagedObjectContext (0x7aecdf10): *** BACKGROUND SAVING (ROOT) ***> on *** BACKGROUND THREAD ***
2015-05-04 19:16:47.963 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7aecdf10) → Save Parents? 1
2015-05-04 19:16:48.023 xxxxx[35555:5570918] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0x7aecdf10) → Save Synchronously? 0
2015-05-04 19:16:48.024 xxxxx[35555:5570924] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0x7aecdf10) Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 4 inserted objects
2015-05-04 19:16:48.026 xxxxx[35555:5570924] __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke21(0x7aecdf10) → Finished saving: <NSManagedObjectContext (0x7aecdf10): *** BACKGROUND SAVING (ROOT) ***> on *** BACKGROUND THREAD ***

saveWithBlockAndWait 是否被错误地实现了,因为它对我不起作用?关于如何解决这个问题的建议或解决方案会很棒.

Is the saveWithBlockAndWait been implemented wrong, since it's not working for me? An advice or solution on how to solve this would be awesome.

推荐答案

您的日志似乎正确.首先它运行您的块,然后将所有内容保存到数据库,然后当前线程继续执行.

Your log seems correct. First it runs your block, then it saves everything to database, then current thread continues execution.

您使用同步方法.同步方法阻塞当前线程,直到它们完成执行.如果您想更新您的界面,您必须在 saveWithBlockAndWait 之后立即执行此操作,或者使用提供完成处理程序的save"方法的异步版本.

You use synchronous method. Synchronous methods block current thread until they finish execution. If you want to update your interface you have to do this right after saveWithBlockAndWait or use async version of "save" method that provides completion handler.

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {

    NSDictionary *users = [responseObject valueForKeyPath:@"responses.user"];
    [User importFromObject:users inContext:localContext];

    NSArray *orders = [responseObject valueForKeyPath:@"responses.orders"];
    [Order importFromArray:orders inContext:localContext];
}];

NSLog(@"Saving done.");

一般情况下,最好使用异步方法,避免阻塞主线程.

Generally, it is better to use async methods to avoid blocking main thread.

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {


   // create or update CoreData models


} completion:^(BOOL contextDidSave, NSError *error) {
   if(error) {
      NSLog(@"Failed to save data");
      return;
   }

   NSLog(@"Saving done.");

   [self.activityIndicator stopAnimating];
}];

这篇关于MagicalRecord 在导入时保存所有内容之前完成块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆