【问题标题】:NSFetchedResultsController sort using child attributeNSFetchedResultsController 使用子属性排序
【发布时间】:2012-05-14 05:54:22
【问题描述】:

我有一对多的父子实体书>借

  • 姓名
  • 借(关系)

  • 借用日期
  • 注意
  • 书(关系)

我想使用子实体的最大NSDateNSFetchedResultsController 中的图书实体进行排序,以显示最近借阅的图书。

我该怎么做?我尝试使用我自己的方法,例如使用 Book 上的 Category

- (NSArray *)borrowSortedByborrowedDate
{
    NSSortDescriptor *sortByCreatedDate = [NSSortDescriptor sortDescriptorWithKey:@"borrowDate" ascending:NO];
    NSArray *sortedArray = [self.histories sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortByCreatedDate]];
    return sortedArray;
}

- (NSDate *)recentBorrowDate
{
    Borrow *borrow = [[self borrowSortedByborrowedDate] objectAtIndex:0];
    return borrow.borrowDate;
}

并将其放入sortDescriptor

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"recentBorrowDate" ascending:YES];

但是没有用。

这是我获取的请求(无效)

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

[fetchRequest setFetchBatchSize:20];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"recentBorrowDate" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

我的预期结果是

  • 书名1(今天借用日期)
  • 书名2(昨天借用日期)
  • 书名3(borrowDate 许多天前)

【问题讨论】:

  • 您能提供获取请求吗?那么您是否针对Book 执行请求?最后,History 是什么,note 又是什么?谢谢。
  • 是的 fetch 请求在没有谓词的情况下针对 Book 执行。我想使用最近借书的 NSDate 对其进行排序。注意是借用的一种属性。
  • 您能提供您正在使用的获取请求吗?您想订购从最近日期到最后一本的书籍吗?谢谢。
  • 我在帖子中添加了获取请求,但没有成功。
  • @art 我目前正试图弄清楚如何做同样的事情

标签: objective-c core-data nsfetchedresultscontroller nssortdescriptor


【解决方案1】:

我有同样的问题,这是我目前实现所需输出的解决方法。 (也许这是唯一的方法,但我还在寻找......)

当创建一个新的 Borrow 时,只需同时更新 book.lastBorrowDate 属性。

// Create new Borrow and set Book
Borrow *newBorrow = (Borrow *)[NSEntityDescription insertNewObjectForEntityForName:@"Borrow" inManagedObjectContext:self.managedObjectContext];
newBorrow.book = theBook;
newBorrow.borrowDate = [NSDate date];
newBorrow.note = theNote;

// Now also update our book's lastBorrowDate tracking property
theBook.lastBorrowDate = [NSDate date];

// Save all our changes
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
    // Something went horribly wrong...
    NSLog(@"Unresolved error: %@, %@, %@", error, [error userInfo],[error localizedDescription]);
    abort(); // Fail
}

现在把它们拉出来很容易......

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

[fetchRequest setFetchBatchSize:20];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastBorrowDate" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

【讨论】:

  • 是的,这与我在等待是否有更好的解决方案时尝试过的方法相同,如果没有更好的解决方案,我也必须使用这个解决方案:(。这有点麻烦,因为你必须手动维护lastBorrowDate,以防您让用户自己编辑借用实体(如重新排序、删除)。
【解决方案2】:

您可能会考虑将lastBorrowedDate 属性添加到您的图书托管对象的可能性。如果您想对该字段进行排序和搜索,则有必要优化您的 MOM 以获得更好的效率。你也可以让代码更简单。

【讨论】:

    【解决方案3】:

    我实际上在类似的情况下也有类似的问题。你可以在这里查看帖子:Custom NSSortDescriptor on complex object

    总而言之,我需要同时使用子属性和实体属性进行排序。找到的唯一解决方法是使用自定义排序描述符并在之后应用过滤器。这意味着您必须执行 fetch,获取 fetchResults,然后将它们排序到一个数组中。不过,我主要担心这种解决方法的性能问题。在您的情况下,自定义排序可能类似于:

    @interface Book(category) {}
    @end
    @implementation Book(category) 
    - (NSDate*)getMostRecentDate {
      NSDate* mostRecentDate = [NSDate dateWithTimeIntervalSince1970:0];
      for(Borrow* b in [self borrows]) {
        mostRecentDate = [mostRecentDate laterDate:[b borrowDate]];
      }
      return mostRecentDate;
    }
    @end
    
    @interface SortDescriptor : NSSortDescriptor {}
    @end
    @implementation SortDescriptor
    - (id)copyWithZone:(NSZone*)zone
    {
        return [[[self class] alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]];
    }
    - (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
    {
        return [[(Book*)object1 getMostRecentDate] compare:[(Book*)object2 getMostRecentDate]];
    }
    @end
    

    让我知道您对此解决方案的看法。我正在开始测试以决定是更改排序以使其更简单还是使用 NSArray。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-21
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多