【问题标题】:Sorting toMany relationship Set in core data排序到多关系集在核心数据中
【发布时间】:2010-11-21 00:56:01
【问题描述】:

我有两个模型 Department 和 Worker。部门与工人有一对多的关系(工人)。 工人有名字字段。如何通过访问 departmet.workers 获取按名字排序的工作人员列表?有没有办法在多对关系中添加排序描述符?

【问题讨论】:

  • 它是一个旧线程.. 但它有效并帮助了我很多时间!为这个线程添加书签谢谢大家..!!

标签: iphone core-data


【解决方案1】:

Core Data 中的多对多关系被建模为无序集。但是,您可以在包含排序描述符的 Department 实体上创建一个 fetched 属性,或者您可以在应用程序中对内存中的集合进行排序(NSArrayController 将通过设置其 sortDescriptors 属性为您完成此操作。

【讨论】:

  • 我会投票支持 fetched 属性,因为它似乎是 Core Data 中“最自然的方式”。
  • @BarryWark 我同意 Karsten 的观点,但我认为最好包含一些有关如何创建描述符的详细信息。经过一番谷歌搜索后,我仍然没有找到如何在获取的属性中进行“排序”描述​​符,只有如何匹配类型查询。
  • 请提供示例
【解决方案2】:

您需要定义自己的方法,例如 sortedWorkers。像这样的:

- (NSArray *)sortedWorkers {
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

    return [self.workers sortedArrayUsingDescriptors:sortDescriptors];
}

【讨论】:

    【解决方案3】:

    Hunter 的代码片段几乎对我有用,除了“workers”是一个 NSSet,我必须先将它加载到 NSMutableArray 中:

    - (NSArray *)sortedWorkers {
        NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
        NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];
    
        NSMutableArray *sortThese = [NSMutableArray arrayWithCapacity:[self.workers count]];
        for (id worker in self.workers) {
            [sortThese addObject:worker];
        }
    
        return [sortThese sortedArrayUsingDescriptors:sortDescriptors];
    }
    

    【讨论】:

      【解决方案4】:

      对 Adrian Hosey 的代码的小改进:

      您也可以这样做,而不是手动迭代所有工作人员:

      -(NSArray *)sortedWorkers {
        NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
        NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];
      
        return [self.workers sortedArrayUsingDescriptors:sortDescriptors];
      }
      

      可能在内部执行与您的迭代完全相同的事情,但也许他们以某种方式使其更高效。打字肯定少了……

      注意:以上仅适用于 iOS 4.0+ 和 OSX 10.6+。在旧版本中,您需要将最后一行替换为:

        return [[self.workers allObjects] sortedArrayUsingDescriptors:sortDescriptors];
      

      【讨论】:

      • 嗯,排序是O(n*log(n)),迭代是O(n)。虽然这是更少的代码,但它肯定更慢。
      • 虽然如此,但代码 sn-ps 之间的区别并不在于一次迭代和一次排序。他们都使用 sort 方法,只是 Adrian 使用 [allObjects] 方法转换为数组,而不是通过迭代集合来手动构建一个数组
      • 从 OS X 10.6 开始,手动迭代和 [allObjects] 都不是必需的,因为 NSSet 本身实现了 sortedArrayUsingDescriptors:,从而避免了临时 NSArray 的多余创建。
      【解决方案5】:

      我注意到这已经很老了,但人们仍然会遇到它(我确实遇到过)

      Adrian Schönig 的帖子很好。我发现它对基础知识很有用,但每次你想访问工人集时都必须这样做。这是非常低效的!

      相反,更好的是每次插入新对象时进行排序,然后将其保存为 CoreData 中的 Set。这意味着每次调用 CoreData 时,都会对工作人员进行排序。

      我使用 NSManagedObject (Worker+Methods.h) 的类别为我的系统执行此操作。在这里,我有一个新 Worker 的 init 方法

      // Worker+Methods.m
      +(Worker *)newWorkerWithFirstname:(NSString *)firstName department:(Department *)department managedContext:(NSManagedObjectContext *)context {
          Worker *w = [NSEntityDescription insertNewObjectForEntityForName:@"Worker" inManagedObjectContext:context];
          w.firstName = firstName;
          w.department = department;
      
          [department orderWorkers];
          return s;
      }
      
      
      //Department+Methods.m
      -(void)orderServices {
          NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
          self.workers = [[NSSet alloc] initWithArray:[self.workers sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortNameDescriptor]]];
      }
      

      显然,当您添加大量工人时,这是低效的,但您可以移动 [department orderWorkers];在添加所有工人之后发生。

      【讨论】:

        【解决方案6】:

        比 Adrian Schönig 的解决方案略有改进:

        现在有必要将self.workers 转换为 NSSet*

        -(NSArray *)sortedWorkers {
           NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
           NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];
        
           return [(NSSet*)self.workers sortedArrayUsingDescriptors:sortDescriptors];
         }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多