- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的应用程序存在竞争条件,多个 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/
对于我正在从事的项目,我使用核心数据来存储应用程序的数据。应用程序从 Internet 加载 XML,并尝试将解析结果生成的对象存储在数据模型中。这曾经工作得很好,直到几天前。我更改了数据模型(在对象
我正在尝试将核心数据中的验证设置为简单的托管对象结构。 有一个 Building 和 Floor 并且两者之间是一对多的关系(在 Building 上有很多 Floors)。 Floor 中的验证器如
我有两个模型: User Company 用户有两个属性: firstName lastName 公司有一个属性: name 用户和公司之间是一对多的(即一个用户可以有多个公司)。 我可以在我的应用程
我的应用程序存在竞争条件,多个 API 请求可能会返回完全相同的数据并尝试保存它们。我想通过在我的模型上添加 validateForInsert 来防止这种情况发生。验证的前提只是检查并查看标识符 k
iPhone forms, where do you put your validation? 人们建议我直接将文本字段的值放入我的核心数据实体中,我也这样做了(请参阅我的第二次编辑)。事情是,当一个
我是一名优秀的程序员,十分优秀!