核心数据关系NSOrderedSet在每个设备上返回不同的顺序

时间:2016-04-05 07:53:42

标签: ios objective-c core-data nsset nsorderedset

我的数据模型中有几个一对多的关系。在每种情况下,重要的是从模型中检索的数据的顺序与其插入的顺序相匹配。我在检查员中勾选了每个关系的“有序”框。我按如下方式添加数据:

NSMutableOrderedSet *set = [destinationEntity mutableOrderedSetValueForKey:relationshipKey];
[set addObject:sourceEntity];
[CoreDataFunctions saveEntity:destinationEntity];

我随后按如下方式检索该集:

NSOrderedSet *set = [sourceEntity valueForKey:relationshipKey];

在添加了数据的设备上,这可以正常工作 - 我可以添加多个实体,它们始终以正确的顺序显示。问题是在通过iCloud同步接收数据的设备上,以不同的顺序返回该集合。始终以相同的顺序提醒您,但与原始设备上输入的顺序不同。

为了解决这个问题,我添加了一个'order'属性,当将对象插入集合时,该属性由递增的整数填充。然后,我可以在从数据模型中检索该密钥后对该密钥进行排序。但是,如果NSOrderedSet没有以可预测的顺序返回,我会情不自禁地觉得有些问题。

我想知道这是否与我在设备从iCloud接收交易时在日志中看到的一些错误有关。我看了很多次,大概是每次交易一次:

  

***错误:此进程调用了一个NSArray-taking方法,例如initWithArray:,并传入一个NSSet对象。现在这种情况正在解决,但很快就会让你感到悲伤。

我认为这是因为数据模型中的对象是NSSet类型,而Core Data正在将它们传递给期待NSArray的东西。但是,我不知道我能做些什么,或者它是否与这个问题有关。我假设它是,因为我怀疑Core Data正在将NSOrderedSet转换为NSArray并且在此过程中丢失了排序。我不能证实这一点。

感激地收到任何建议!

1 个答案:

答案 0 :(得分:0)

最可靠的方法是创建一个Abstract Entity,如BaseEntity,数据模型中的每个其他类都继承该BaseEntitydateCreated会在您awakeFromInsert子类的NSManagedObject中设置NSSortDescriptor属性。

然后,当您执行获取请求时,您可以使用dateCreated指定要排序的SQLite,这非常快,特别是如果您使用的是ordered

如果您这样做,那么您可以取消选中CoreData中的Entity按钮。

编辑:以下是托管对象子类中的排序关系的示例:

给定具有CoreData生成关系属性的实体@property (nullable, nonatomic, retain) NSSet<Entity *> *toManyRelationship;

@property (nullable, nonatomic, strong, readonly) NSArray<Entity *> *orderedToManyRelationship;

然后您可以创建自己的属性:

@dynamic toManyRelationship;

- (NSArray<Entity *> *)orderedToManyRelationship
{
    NSSortDescriptor *dateSorter = [NSSortDescriptor sortDescriptorWithKey:@"dateCreated" ascending:YES];

    return [[self.toManyRelationship allObjects] sortedArrayUsingDescriptors:@[dateSorter]];
}

这是这样实现的:

background: rgba{0,0,0,0);