MagicalRecord:如何在后台保存导入的数据 [英] MagicalRecord: How to save imported data in background

查看:731
本文介绍了MagicalRecord:如何在后台保存导入的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将数据导入Core Data,并将其保存在MagicalRecord 的后台线程中。

I'm trying to import data into Core Data and save it in a background thread with MagicalRecord.

要执行此操作:

__block User *user = nil;
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext)
{
     user = [User MR_findFirstOrCreateByAttribute:@"userId" withValue:userId inContext:localContext];
     [user MR_importValuesForKeysWithObject:responseObject];
}];

[User setCurrentUser:user];

当我在块内时,用户是正确的。完成块之后 user 是一个 对象,但没有设置任何属性。

User is correct when I'm inside the block. After the block is completed user is a NSManagedObject object, but doesn't have any attributes set.

另一方面,这是工作原理:

This, on the other hand, works:

OEUser *user = [OEUser MR_findFirstOrCreateByAttribute:@"userId" withValue:userId];                               
[user MR_importValuesForKeysWithObject:responseObject];
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
[User setCurrentUser:user];

但我想保存在后台。

我也试过这个没有效果。

I also tried this to no avail.

User *user = [User MR_findFirstOrCreateByAttribute:@"userId" withValue:userId];
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext)
{
     User *localUser = [user MR_inContext:localContext];
     [user MR_importValuesForKeysWithObject:responseObject];
}];

[User setCurrentUser:user];

这里的问题似乎是 [user MR_inContext:localContext] code>返回 nil

我对Core Data很新,所以如果我缺少一些明显的东西。

I'm pretty new to Core Data, so bear with me if I'm missing something obvious.

推荐答案

当您使用 * Wait 方法时,任何异步,并且您仍将在导入期间阻止您的主线程。你应该确实使用块方法,但这确保任何Core Data操作在正确的线程( NSManagedObjectContext 创建的线程)上执行。

When you use the *Wait method you are not gaining any asynchronicity and you will still be blocking your main thread during the import. You should indeed be using the block methods but this to ensure that any Core Data operations are performed on the correct thread (the thread the NSManagedObjectContext was created on).

当使用 saveWithBlockAndWait: MagicalRecord在后台线程上创建一个新的上下文来执行它的工作。然后,这个新创建的上下文将生成到您的块中,并且仅在块的范围内生效。您不能在上下文之间传递 NSManagedObject ,因此您不应该尝试从块外捕获用户。

When you use saveWithBlockAndWait: MagicalRecord creates a new context on a background thread to perform it's work on. This newly created context is then yielded to your block and lives only for the scope of the block. You can not pass NSManagedObject's between contexts so you should not be trying to capture the user from outside the block.

我可以想象第二个例子只会在创建一个新的 User 的情况下失败,因为你调用 MR_findFirstOrCreateByAttribute:withValue:这将在内存中创建一个新的 NSManagedObject ,但是这不会持久到存储,因此在 saveWithBlockAndWait:没有用户可以从商店拉。

I can imagine the second example will only actually be failing in the case of creating a new User because you call MR_findFirstOrCreateByAttribute:withValue: which will create a new NSManagedObject in memory but this is not persisted to the store therefore inside the saveWithBlockAndWait: there is no User to pull from the store.

正确的方式是

[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
  User *localUser = [User MR_findFirstOrCreateByAttribute:@"userId" 
                                                withValue:userId     
                                                inContext:localContext];
  [user MR_importValuesForKeysWithObject:responseObject];
}];

User *user = [User MR_findFirstByAttribute:@"userId" withValue:userId];

[User setCurrentUser:user];

如上所述,这将阻塞主线程,因此您可能需要考虑移动到 saveWithBlock:completion:而不是在后台执行工作,而不是阻塞当前线程。

As mentioned this will block the main thread so you may want to consider moving to saveWithBlock:completion: instead which will perform the work in the background and not block the current thread.

更好的是,到一个实际的 User 对象,而是保持在 userId ,这将安全你头痛下来,当人们开始访问来自各种线程的 currentUser

Even better I would consider not holding onto an actual User object but instead hold onto the userId, which will safe you headaches down the line when people start accessing the currentUser from all kinds of threads

这篇关于MagicalRecord:如何在后台保存导入的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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