导入时保存所有内容之前的 MagicalRecord 完成块

Posted

技术标签:

【中文标题】导入时保存所有内容之前的 MagicalRecord 完成块【英文标题】:MagicalRecord finish block before everything is saved on import 【发布时间】:2015-05-04 17:29:18 【问题描述】:

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

它转到一个新的 ViewController,它有一个 UITableView 来显示新导入的数据。

我的问题是,这个成功块被称为之前 MagicalRecord 完成与储蓄。因此UITableView 尚未收到要显示的订单对象。

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

[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(witch 是 ViewController,也有 segue)是另一个NSLog,问题可能就在这里。

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

该应用程序在我第二次发布时运行良好。只有第一次登录我有这个问题

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 是否执行错误,因为它不适合我?关于如何解决这个问题的建议或解决方案会很棒。

【问题讨论】:

【参考方案1】:

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

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

[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.");

一般来说,最好使用异步方法来避免阻塞主线程。

[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];
];

【讨论】:

我同意。最好使用异步方法。在我得到一个异常之前,因为我试图阻止成功,但是该变量在这个块中也用作 BOOL - 我今天早上才看到它,这就是我没有使用 saveWithBlock 的原因。我现在更改了我的代码,因此该块被称为成功。感谢您的帮助

以上是关于导入时保存所有内容之前的 MagicalRecord 完成块的主要内容,如果未能解决你的问题,请参考以下文章

CKEditor4x word导入不保存格式的解决方案

导入过程中断

如何把PPT内容导入微信公众号?

如何将导出的confluence空间及所有页面 导入到另一个confluence系统

python学习-模块

如何把PPT内容导入微信公众号?