1

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

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

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

NSOrderedSet *set = [sourceEntity valueForKey:relationshipKey];

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

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

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

*** 错误:该进程调用了一个 NSArray 获取方法,例如 initWithArray:,并传入了一个 NSSet 对象。目前正在解决此问题,但很快就会让您感到悲伤。

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

任何建议都感激不尽!

4

1 回答 1

0

最可靠的方法是创建一个Abstract Entitylike BaseEntity,数据模型中的每个其他类都继承自该like。BaseEntity将具有您在子类dateCreated中设置的属性。awakeFromInsertNSManagedObject

然后,当您执行 fetch 请求时,您可以指定NSSortDescriptor使用 this 进行排序dateCreated非常快,特别是如果您使用SQLite.

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

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

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]];
}
于 2016-04-05T08:35:08.833 回答