Magical Records:加载要在本地上下文中更新的记录
Posted
技术标签:
【中文标题】Magical Records:加载要在本地上下文中更新的记录【英文标题】:Magical Records: Loading a record to be updated in a local context 【发布时间】:2014-09-19 15:23:27 【问题描述】:我目前正在使用 Magical Records 保存记录,如下所示:
NSManagedObjectID *objID = [existingItem objectID];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
CustomNSMO *item;
if(newItem) item = [CustomNSMO MR_createEntityInContext:localContext];
else item = [localContext objectWithID:objID];
item.sync = 1;
item.relID = @"Some String";
completion:^(BOOL success, NSError *error)
//do something
];
这很好用。如果我查询所有设置了 sync 的项目,我会得到我期望的结果,即
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(sync >= 1)"];
NSArray *objects = [CustomNSMO MR_findAllSortedBy:@"sync" ascending:YES withPredicate:predicate];
给我一个我的新对象或更新对象的数组。
然后我(在一些服务器业务之后)想要找到所有 sync >= 1 的结果并将其设置为零。这是发生奇怪行为的时候。我一直在尝试通过任一方式在本地上下文中获取一系列结果
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_context];
NSArray *objects = [CustomNSMO MR_findAllSortedBy:@"sync" ascending:YES withPredicate:predicate inContext:localContext];
for(CustomNSMO *item in objects)
item.sync = 0;
[localContext MR_saveToPersistentStoreAndWait];
或
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
NSArray *objects = [CustomNSMO MR_findAllSortedBy:@"sync" ascending:YES withPredicate:predicate inContext:localContext];
for (SyncObject *currentObj in objects)
currentObj.sync = @0;
completion:nil];
如果在第一次创建项目时设置了 relID,那么这一切都很好。我可以编辑项目(更改 relID)并且在所有上下文中都可以观察到更改。但是,如果第一次创建项目时,它的 relID 为 nil,那么在使用上面的代码执行以下操作后会出现问题:
1) 更新项目,将 nil relID 更改为某个非nil 值
2) 将项目保存到数据库中
3) 加载项目(通过搜索'sync')
在 MR_defaultContext 之外的任何上下文中,relID 保持为 nil。如果我查看 MR_defaultContext 中的对象,我会看到正确更新的 relID。如果我在不同的上下文中查看它,它是 nil。这意味着本地上下文中 sync 的更新会覆盖默认上下文中 relID 的值(将其设置为 nil)。
【问题讨论】:
【参考方案1】:一些想法:
if(newItem) item = [CustomNSMO MR_createEntityInContext:context];
应该是:
if(newItem) item = [CustomNSMO MR_createEntityInContext:localContext];
您不想在 +saveWithBlock:
中使用不同的上下文。
另外,这一行:
else item = [localContext objectID];
我想你的意思是[localContext objectWithID:objID]
或[localContext existingObjectWithID:objID error:error]
?
【讨论】:
您是对的,但这些只是我的示例中的拼写错误(我简化了原始代码)。我已经编辑了上面的代码。 好的,接下来请确保您在没有看到更新值的上下文中刷新/重新获取,或者观察 contextDidSave 通知并合并更改。 我没有看到更改的上下文是在我更改 sync 属性并重新保存之前创建的。我原以为此上下文将基于 MR_defaultContext 的值(确实显示了更改),因此不需要任何合并。基本过程是saveWithBlock,然后再次完成saveWithBlock。第二个块的上下文不反映第一个块的变化。但是在第二个块中查询 defaultContext 确实显示了第一个块的变化。 Nick,你可以尝试将 MagicalRecord 更新到 2.3 版吗? 不使用[NSManagedObjectContext MR_context]
,而是分配并初始化具有适当并发类型的上下文,并将其parentContext属性设置为MR_defaultContext
【参考方案2】:
原来这是我们在 Core Data 下使用的数据库存储的一个错误。
https://github.com/project-imas/encrypted-core-data/issues/118
【讨论】:
以上是关于Magical Records:加载要在本地上下文中更新的记录的主要内容,如果未能解决你的问题,请参考以下文章
Magical Records - 如何使用关键路径映射关系?
我正在尝试从 Magical Records 获取最新添加的数据