【问题标题】:sort data using Realm使用 Realm 对数据进行排序
【发布时间】:2017-07-08 00:27:34
【问题描述】:

我最近从 Coredata 搬到了 Realm。在我的应用程序中,我显示了 50K + contacts 。

联系人对象的格式为:

联系人:名字、姓氏、公司

我正在尝试获取 Realm 中的所有联系人,并且我正在尝试显示这些联系人,类似于 iPhone 中的本机联系人应用程序。

首先,我根据联系人名字创建部分标题:

-(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 秒,这很好,但我正在寻找改进此数据获取的方法。

【问题讨论】:

    标签: ios objective-c realm contacts


    【解决方案1】:

    Realm 的工作原理是延迟加载,在您第一次真正“触摸”它们之前,不会加载对象及其属性。

    因此,如果您执行任何操作,即一次手动迭代结果集中的所有 Realm 对象,或者手动将特定对象复制到数组,您将招致性能损失,这将增加你在 Realm 中持久化的对象越多。

    将性能影响降至最低的最佳方法是尝试减少迭代结果集的次数,并尽可能避免将对象复制出数组。 RLMResults 的行为类似于数组,因此对于大多数情况,您通常可以只使用该对象。

    prepareDataSource 方法中,与其循环遍历每个对象并将它们传递给NSMutableArray,不如考虑传递RLMResults 对象本身。

    getSectionTitleBasedOn: 方法似乎也非常低效,因为您要遍历每个对象以检查是否存在具有特定第一个字符的条目。相反,您可以创建一个字母索引,然后对以每个字母开头的条目进行领域查询,然后检查生成的 RLMResults 对象是否具有正计数(虽然我不确定这是否实际上会更快)。

    但最后,有时当您进行这样的复杂排序时,没有“聪明”的方法可以避免遍历数据库中的每个对象(即使是 Realm 在执行排序时也必须在内部加载每个对象),性能下降是不可避免的,在这种情况下,您还应该确保您的 UI 有向用户显示“工作”指示器的规定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 2015-05-25
      • 2022-01-07
      • 1970-01-01
      相关资源
      最近更新 更多