Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在每个设备上返回不同顺序的核心数据集_Ios_Objective C_Core Data_Nsset_Nsorderedset - Fatal编程技术网

Ios 在每个设备上返回不同顺序的核心数据集

Ios 在每个设备上返回不同顺序的核心数据集,ios,objective-c,core-data,nsset,nsorderedset,Ios,Objective C,Core Data,Nsset,Nsorderedset,我的数据模型中有几个一对多关系。在每种情况下,从模型中检索的数据顺序都必须与插入数据的顺序相匹配。我已在inspector中的每个关系的“Ordered”框中打勾。我将数据添加如下: NSMutableOrderedSet *set = [destinationEntity mutableOrderedSetValueForKey:relationshipKey]; [set addObject:sourceEntity]; [CoreDataFunctions saveEntity:desti

我的数据模型中有几个一对多关系。在每种情况下,从模型中检索的数据顺序都必须与插入数据的顺序相匹配。我已在inspector中的每个关系的“Ordered”框中打勾。我将数据添加如下:

NSMutableOrderedSet *set = [destinationEntity mutableOrderedSetValueForKey:relationshipKey];
[set addObject:sourceEntity];
[CoreDataFunctions saveEntity:destinationEntity];
NSOrderedSet *set = [sourceEntity valueForKey:relationshipKey];
我随后按如下方式检索该集:

NSMutableOrderedSet *set = [destinationEntity mutableOrderedSetValueForKey:relationshipKey];
[set addObject:sourceEntity];
[CoreDataFunctions saveEntity:destinationEntity];
NSOrderedSet *set = [sourceEntity valueForKey:relationshipKey];
在添加数据的设备上,这很好——我可以添加多个实体,它们总是以正确的顺序显示。问题在于,在通过iCloud同步接收数据的设备上,数据集以不同的顺序返回。请记住,顺序始终相同,但与在原始设备上输入的顺序不同

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

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

***错误:此进程调用了NSArray获取方法,如initWithArray:,并传入了NSSet对象。这项工作目前正在进行中,但很快会给你带来痛苦

我假设这是因为数据模型中的对象属于NSSet类型,而核心数据正在将它们传递给需要NSArray的对象。然而,我不知道我能做些什么,或者它是否与这个问题有关。我假设是这样,因为我怀疑核心数据正在将NSOrderedSet转换为NSArray,并在这个过程中丢失了顺序。但我不能证实这一点


感谢您的建议

最可靠的方法是创建一个
抽象实体
,如
BaseEntity
,数据模型中的所有其他类都从该实体继承
BaseEntity
将有一个
dateCreated
属性,您可以在
NSManagedObject
子类的
awakeFromInsert
中设置该属性

然后,当执行提取请求时,可以指定
NSSortDescriptor
使用
dateCreated
进行排序,这非常快,尤其是在使用
SQLite

如果执行此操作,则可以取消选中CoreData中的
ordered
按钮

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

给定具有CoreData生成的关系属性的实体<代码>实体

@property (nullable, nonatomic, retain) NSSet<Entity *> *toManyRelationship;
@property (nullable, nonatomic, strong, readonly) NSArray<Entity *> *orderedToManyRelationship;
@property(可空、非原子、保留)NSSet*toManyRelationship;
然后,您可以创建自己的属性:

@property (nullable, nonatomic, retain) NSSet<Entity *> *toManyRelationship;
@property (nullable, nonatomic, strong, readonly) NSArray<Entity *> *orderedToManyRelationship;
@property(可空、非原子、强、只读)NSArray*orderedToManyRelationship;
这是这样实现的:

@dynamic toManyRelationship;

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

    return [[self.toManyRelationship allObjects] sortedArrayUsingDescriptors:@[dateSorter]];
}
@动态关系;
-(NSArray*)OrderedTomany关系
{
NSSortDescriptor*日期排序器=[NSSortDescriptor SortDescriptor WithKey:@“dateCreated”升序:是];
使用描述符返回[[self.toManyRelationship allObjects]sortedarray:@[dateSorter]];
}

最可靠的方法是创建一个
抽象实体
,如
BaseEntity
,数据模型中的所有其他类都从该实体继承
BaseEntity
将有一个
dateCreated
属性,您可以在
NSManagedObject
子类的
awakeFromInsert
中设置该属性

然后,当执行提取请求时,可以指定
NSSortDescriptor
使用
dateCreated
进行排序,这非常快,尤其是在使用
SQLite

如果执行此操作,则可以取消选中CoreData中的
ordered
按钮

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

给定具有CoreData生成的关系属性的实体<代码>实体

@property (nullable, nonatomic, retain) NSSet<Entity *> *toManyRelationship;
@property (nullable, nonatomic, strong, readonly) NSArray<Entity *> *orderedToManyRelationship;
@property(可空、非原子、保留)NSSet*toManyRelationship;
然后,您可以创建自己的属性:

@property (nullable, nonatomic, retain) NSSet<Entity *> *toManyRelationship;
@property (nullable, nonatomic, strong, readonly) NSArray<Entity *> *orderedToManyRelationship;
@property(可空、非原子、强、只读)NSArray*orderedToManyRelationship;
这是这样实现的:

@dynamic toManyRelationship;

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

    return [[self.toManyRelationship allObjects] sortedArrayUsingDescriptors:@[dateSorter]];
}
@动态关系;
-(NSArray*)OrderedTomany关系
{
NSSortDescriptor*日期排序器=[NSSortDescriptor SortDescriptor WithKey:@“dateCreated”升序:是];
使用描述符返回[[self.toManyRelationship allObjects]sortedarray:@[dateSorter]];
}

感谢您的快速回复。只有几个问题。首先,这种方法是否意味着为我的实体使用NSManagedObject子类?我目前正在使用helper方法和KVC,因此我可以更好地控制值的设置和保存。例如,我有一个助手方法来设置实体上的键/值,然后保存实体。第二,如果我在不使用获取请求的情况下获取关系集,这种方法会有所不同吗?例如,通过直接访问包含集合的属性。第三,如果实体的创建速度很快(即彼此之间的间隔不到一秒钟),那么创建日期是否有效?确定1)不一定是所有实体,但最简单的方法是将
基本实体子类化。注意:子类化可能是有益的,因为您可以进行类型检查和IDE自动完成,从而避免恼人的错误。2) 如果直接访问该属性,则必须对返回的对象应用
排序描述符。(如果您将其子类化,您可以在类本身中执行此操作。)3)是的,只要它们按创建顺序插入到
NSManagedObjectContext
中。谢谢@RASS,这非常有用。我还意识到我的保存策略效率很低(基本上每次更改属性值时都保存上下文…)我现在已经实现了一个定时保存我