gpt4 book ai didi

objective-c - 使用 validateForInsert 防止核心数据重复

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:46:22 25 4
gpt4 key购买 nike

我的应用程序存在竞争条件,多个 API 请求可能会返回完全相同的数据并尝试保存它们。我想通过在我的模型上添加 validateForInsert 来防止这种情况发生。验证的前提只是检查并查看标识符 key 是否已经存在

- (BOOL)validateForInsert:(NSError *__autoreleasing *)error
{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([CWDeal class])];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"identifier == %@", self.identifier];
NSError *validateError;
int count = [[(CWAppDelegate *)[[UIApplication sharedApplication] delegate] privatewriterManagedObjectContext] countForFetchRequest:fetchRequest error:&validateError];
if (count > 0) {
return FALSE;
}
return [super validateForInsert:error];
}

问题是什么都没有保存。我有一个 managedObjectContext(主线程),它有一个 privateWriterManagedObjectContext(连接到 PSC)的父级。当我导入东西时,我将创建一个 importContext(一些后台线程),它有一个 managedObjectContext 的父级。当我获取新数据并尝试保存流程时,会是这样的。

(记住验证是检查对象的 privateWriterMOC)

在 importContext 上创建对象 -> 保存 -> 验证 -> 好的。

(数据被推送到 importContext 的父级 managedObjectContext)。

保存 managedObjectedContext -> 验证 -> 好的。

(数据被推送到 managedObjectContext 的父级 privateWriterMOC)。

保存 privateWriterMOC -> 验证 -> 失败。 privateWriterMOC 认识到对象在其上下文中并且不会保存它们。

似乎没有很多关于使用 validateForInsert 的文档,所以我希望有人对如何执行此操作有建议?

最佳答案

这是我用于生产的代码:

- (BOOL)validateForInsert:(NSError *__autoreleasing *)error {
[[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator] lock];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Deal class])];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"identifier == %@", self.identifier];
NSError *validateError;
int count = [[(AppDelegate *)[[UIApplication sharedApplication] delegate] validationContext] countForFetchRequest:fetchRequest error:&validateError];
if (count > 0) {
[[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator] unlock];
return FALSE;
}
[[(CWAppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator] unlock];
return [super validateForInsert:error];
}

锁定 PSC 是这项工作的关键。之前,当不同的上下文试图同时联系 PSC 时,我遇到了很多死锁。我发现这种方法的唯一缺陷是,如果一个对象返回 false,整个上下文将被标记为无效并且不会保存。假设你有很多好对象,但一个坏对象都在未保存的上下文中,那个坏对象将不允许好对象保存。我在测试时遇到了这个问题,但在生产中我没有发现任何问题。


我将发布一个我在写问题时想出的答案并刚刚测试过。我不知道这是否正确,但目前似乎是为了防止重复。

我所做的是在我的 appDelegate 中创建另一个名为 validationContext 的上下文,并将其设置为与 privateWriterMOC 完全相同。基本上这个想法是它只连接到商店并且它知道的唯一数据已经被写入。当调用 validateForInsert 时,我使用 validationContext 执行提取,如果该对象已经保存,它会通知我。

我相信竞争条件仍然可能发生(假设写入和提取同时发生并且提取首先返回)但我会更多地研究它(也许 sqlite3 db 是原子的?)。竞争条件是一个非常极端的情况,但我只是想处理它以防万一。

关于objective-c - 使用 validateForInsert 防止核心数据重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13980640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com