2014-05-20 25 views
3

我试图数据导入到核心数据,并将其与MagicalRecord保存在后台线程。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是一个NSManagedObject对象,但没有设置任何属性。

此,在另一方面,工作原理:

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

但我希望将其保存在后台。


我也试过这个无济于事。

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]返回

我对Core Data很新,所以如果我错过了一些明显的东西,请耐心等待。

回答

4

当您使用*Wait方法时,您没有获得任何异步性,并且在导入过程中仍然会阻止您的主线程。您确实应该使用块方法,但是这样做可以确保任何核心数据操作都在正确的线程上执行(创建线程NSManagedObjectContext)。

当你使用saveWithBlockAndWait: MagicalRecord在后台线程创建一个新的上下文来执行它的工作。这个新创建的上下文然后被放到你的块中,并且只在块的范围内生存。你不能在上下文之间传递NSManagedObject,所以你不应该试图从块外部捕获用户。

我能想象第二个例子实际上只在创建一个新的User的情况下失败,因为你叫MR_findFirstOrCreateByAttribute:withValue:这将在内存中创建一个新的NSManagedObject但这不是坚持到商店因此saveWithBlockAndWait:里面有没有User从商店拉。

正确的方法是

[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:,而不是将在后台执行的工作,并不会阻止当前线程。

更妙的是,我会考虑不持有到实际User对象,而是守住userId,这将安全你头疼的路线,当人们开始从各种线程访问currentUser

+0

感谢伟大的答案。其他问题:在我的第二个失败的例子中,是否有任何方式访问在块创建的本地上下文中创建的默认上下文(尚未保存)的用户?或者唯一的方法是事先保存默认的上下文? –

相关问题