jar*_*air 18 sqlite core-data ios watchkit ios-extensions
为了有效地提出我的问题,我们首先考虑一下我面临的确切情况:
常规设置
导致问题的事件顺序
用户启动主机应用程序.它开始从远程API资源获取数据.核心数据模型对象基于API响应创建,并"upserted"到主机应用程序的托管对象上下文中.每个API实体都有一个uniqueID,用于在远程API后端中标识它.通过"upsert",我的意思是,对于每个API实体,主机应用程序仅在无法找到给定唯一ID的现有条目时在Core Data中创建新条目.
同时,用户还启动了一个主机应用程序的扩展.它也可以从同一个远程API执行某种提取.它还尝试在解析API响应时执行"upsert".
问题:如果主机应用程序和扩展程序同时尝试为同一API实体插入Core Data条目,会发生什么?要了解这是如何产生的,让我们看看upsert的事件序列:
核心数据Upsert序列:
uniqueID等于已解析的唯一ID.uniqueID属性设置为已解析的uniqueID.问题详情
假设主机应用程序和扩展程序同时独立地解析同一API实体的API响应.如果主机应用程序和扩展程序在它们中的任何一个完成步骤4之前到达步骤3,则它们都将尝试为相同的唯一ID插入新的核心数据条目.当他们到达步骤4并调用save:他们各自的托管对象上下文时,Core Data将很乐意创建重复的条目.
据我所知,Core Data没有任何方法可以将属性标记为唯一.我需要一个等同于SQLite INSERT OR IGNORE+ UPDATE组合的核心数据..或者我需要一种方法来"锁定"持久存储的SQLite后备存储,这听起来像是一个麻烦的方法.
对iOS 8扩展引入的这个相当新颖的问题有一个已知的方法吗?
Tom*_*ton 10
对iOS 8扩展引入的这个相当新颖的问题有一个已知的方法吗?
是的,这与将iCloud与Core Data一起使用时采用的方法相同:让重复发生,然后再进行清理.这两种情况都存在创建重复条目的风险,并且没有完全可靠的方法来阻止它们.因为你有一把uniqueID钥匙,所以就你而言,你的状态很好.
正如Dave DeLong指出的那样,首先要避免这个问题会容易得多.如果这是不可能的,你可以通过一些额外的工作来处理它.
找到重复的东西是这样的:
NSError *error = nil;
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:self.persistentStoreCoordinator];
NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"MyEntityName"];
[fr setIncludesPendingChanges:NO];
NSExpression *countExpr = [NSExpression expressionWithFormat:@"count:(uniqueID)"];
NSExpressionDescription *countExprDesc = [[NSExpressionDescription alloc] init];
[countExprDesc setName:@"count"];
[countExprDesc setExpression:countExpr];
[countExprDesc setExpressionResultType:NSInteger64AttributeType];
NSAttributeDescription *uniqueIDAttr = [[[[[_psc managedObjectModel] entitiesByName] objectForKey:@"MyEntityName"] propertiesByName] objectForKey:@"uniqueID"];
[fr setPropertiesToFetch:[NSArray arrayWithObjects:uniqueIDAttr, countExprDesc, nil]];
[fr setPropertiesToGroupBy:[NSArray arrayWithObject:uniqueIDAttr]];
[fr setResultType:NSDictionaryResultType];
NSArray *countDictionaries = [moc executeFetchRequest:fr error:&error];
Run Code Online (Sandbox Code Playgroud)
这几乎就是SQL中类似这样的核心数据:
SELECT uniqueID, COUNT(uniqueID) FROM MyEntityName GROUP BY uniqueID;
Run Code Online (Sandbox Code Playgroud)
您将获得一个字典数组,每个字典都包含一个字典uniqueID和计数值的计数.运行字典并适当处理重复项.
我在博文中更详细地描述了这一点.还有一个来自Apple的示例项目,演示了名为SharedCoreData的过程,但我相信它只作为WWDC 2012示例代码包的一部分提供.该会议的会议227也对此进行了描述.
| 归档时间: |
|
| 查看次数: |
3032 次 |
| 最近记录: |