使用 Realm 对数据进行排序
sort data using Realm
我最近从 Coredata 搬到了 Realm。在我的应用程序中,我显示了 50K + 联系人。
联系人 object 的格式为:
联系人:名字、姓氏、公司
我试图获取 Realm 中的所有联系人,并且我试图在 iPhone.
中显示类似于本机联系人应用程序的联系人
首先,我根据联系人的名字创建 header 部分标题:
-(NSArray *)getSectionTitleBasedOn:(NSString*)sortBy{
RLMResults *results = [self getMainDataSetFromRealm];
ContactSource *contactSource = results.firstObject;
NSMutableDictionary *nameDic = [NSMutableDictionary dictionary];
for (RealmContact *contact in contactSource.contacts){
if (contact.firstName.length>0) {
if ([sortBy isEqualToString:@"FirstName"]) {
[nameDic setObject:@"firstletter" forKey:[contact.firstName substringToIndex:1]];
}
}
}
NSLog(@"dic %@",nameDic);
return [[nameDic allKeys]sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}
这为我提供了一组代表章节标题的字母。
现在我正在为每个部分准备数据源,所以对于部分 A,我正在获取所有以字母 'A'
开头的联系人
-(void)prepareDataSource:(NSArray *)titleArr{
RLMResults *results = [self getMainDataSetFromRealm];
ContactSource *contactSource = results.firstObject;
__block NSMutableDictionary *dataSource = [NSMutableDictionary dictionary];
[titleArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *sectionHeader = obj;
RLMResults *contactResults = [contactSource.contacts objectsWhere:[NSString stringWithFormat:@"firstName BEGINSWITH '%@'",sectionHeader]];
NSMutableArray *contactRowArr = [NSMutableArray array];
for (Contact *contact in contactResults){
[contactRowArr addObject:contact];
}
[dataSource setObject:contactRowArr forKey:sectionHeader];
}];
_dataSource = [dataSource copy];
[self.tableView reloadData];
}
这非常有效,但需要 3-5 秒才能加载 table 这很好,但我正在寻找改进此数据获取的方法。
Realm 的工作原理是延迟加载,其中对象及其属性只有在您真正 'touch' 第一次加载它们时才会加载。
因此,如果您执行任何操作,同时手动遍历结果集中的所有 Realm 对象,或手动将特定对象复制到数组,您将导致性能下降将增加你在 Realm 中持久化的对象。
将性能影响降到最低的最佳方法是尝试减少迭代结果集的次数,并尽可能避免将对象复制出数组。 RLMResults
表现得像一个数组,因此在大多数情况下,您通常可以只使用该对象。
在 prepareDataSource
方法中,您可以考虑传递 RLMResults
对象本身,而不是遍历每个对象并将它们传递给那个 NSMutableArray
。
方法 getSectionTitleBasedOn:
似乎也很低效,因为您要遍历每个对象以检查是否存在具有特定第一个字符的条目。相反,您可以创建一个字母表索引,然后对以每个字母开头的条目执行 Realm 查询,然后检查生成的 RLMResults
对象是否具有正计数(虽然我不确定如果这实际上会更快)。
但最后,有时当你像这样进行复杂排序时,没有 'clever' 方法来避免遍历数据库中的每个对象(即使是 Realm 在执行时也必须在内部加载每个对象一种),性能下降是不可避免的,在这种情况下,您还应该确保您的 UI 有向用户显示 'working' 指示器的规定。
我最近从 Coredata 搬到了 Realm。在我的应用程序中,我显示了 50K + 联系人。
联系人 object 的格式为:
联系人:名字、姓氏、公司
我试图获取 Realm 中的所有联系人,并且我试图在 iPhone.
中显示类似于本机联系人应用程序的联系人首先,我根据联系人的名字创建 header 部分标题:
-(NSArray *)getSectionTitleBasedOn:(NSString*)sortBy{
RLMResults *results = [self getMainDataSetFromRealm];
ContactSource *contactSource = results.firstObject;
NSMutableDictionary *nameDic = [NSMutableDictionary dictionary];
for (RealmContact *contact in contactSource.contacts){
if (contact.firstName.length>0) {
if ([sortBy isEqualToString:@"FirstName"]) {
[nameDic setObject:@"firstletter" forKey:[contact.firstName substringToIndex:1]];
}
}
}
NSLog(@"dic %@",nameDic);
return [[nameDic allKeys]sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}
这为我提供了一组代表章节标题的字母。
现在我正在为每个部分准备数据源,所以对于部分 A,我正在获取所有以字母 'A'
开头的联系人-(void)prepareDataSource:(NSArray *)titleArr{
RLMResults *results = [self getMainDataSetFromRealm];
ContactSource *contactSource = results.firstObject;
__block NSMutableDictionary *dataSource = [NSMutableDictionary dictionary];
[titleArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *sectionHeader = obj;
RLMResults *contactResults = [contactSource.contacts objectsWhere:[NSString stringWithFormat:@"firstName BEGINSWITH '%@'",sectionHeader]];
NSMutableArray *contactRowArr = [NSMutableArray array];
for (Contact *contact in contactResults){
[contactRowArr addObject:contact];
}
[dataSource setObject:contactRowArr forKey:sectionHeader];
}];
_dataSource = [dataSource copy];
[self.tableView reloadData];
}
这非常有效,但需要 3-5 秒才能加载 table 这很好,但我正在寻找改进此数据获取的方法。
Realm 的工作原理是延迟加载,其中对象及其属性只有在您真正 'touch' 第一次加载它们时才会加载。
因此,如果您执行任何操作,同时手动遍历结果集中的所有 Realm 对象,或手动将特定对象复制到数组,您将导致性能下降将增加你在 Realm 中持久化的对象。
将性能影响降到最低的最佳方法是尝试减少迭代结果集的次数,并尽可能避免将对象复制出数组。 RLMResults
表现得像一个数组,因此在大多数情况下,您通常可以只使用该对象。
在 prepareDataSource
方法中,您可以考虑传递 RLMResults
对象本身,而不是遍历每个对象并将它们传递给那个 NSMutableArray
。
方法 getSectionTitleBasedOn:
似乎也很低效,因为您要遍历每个对象以检查是否存在具有特定第一个字符的条目。相反,您可以创建一个字母表索引,然后对以每个字母开头的条目执行 Realm 查询,然后检查生成的 RLMResults
对象是否具有正计数(虽然我不确定如果这实际上会更快)。
但最后,有时当你像这样进行复杂排序时,没有 'clever' 方法来避免遍历数据库中的每个对象(即使是 Realm 在执行时也必须在内部加载每个对象一种),性能下降是不可避免的,在这种情况下,您还应该确保您的 UI 有向用户显示 'working' 指示器的规定。