0

设想 :

我有一个费用跟踪 iOS 应用程序,我将费用从费用详细视图控制器存储到表视图中,该表视图显示费用列表以及类别和金额。

在 tableview 的顶部,是一个带有 CALENDAR 按钮的 UIView、一个显示日期的 UILabel 文本(例如:2012 年 10 月 23 日(Sun))和侧面的另外 2 个按钮。按下日历按钮会打开一个带有当前日期的自定义日历,这两个按钮用于相应地减少和增加日期。

我想根据我的核心数据实体“费用”中的属性日期来保存费用。

问题:假设我按下日历按钮并从那里选择一些随机日期,它下面的表格视图应该显示当天的特定费用。我的意思是我希望表格视图只显示特定日期的费用,如果我按下增加日期或减少日期的按钮,表格视图应该显示当天的费用。我正在使用 NSFetchedResultsController 和 Core Data 来节省开支。

关于我将如何实现这一目标的任何想法?这是FRC的代码。

-(NSFetchedResultsController *)fetchedResultsController

{

if(_fetchedResultsController != nil)
{
return _fetchedResultsController;
}

AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

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

[request setEntity:[NSEntityDescription entityForName:@"Money" inManagedObjectContext:context]];

NSSortDescriptor *sortDescriptor1 =
[[NSSortDescriptor alloc] initWithKey:@"rowNumber"
                        ascending:YES];

NSArray * descriptors = [NSArray arrayWithObjects:sortDescriptor1, nil];

[request setSortDescriptors: descriptors];
[request setResultType: NSManagedObjectResultType];
[request setIncludesSubentities:YES];

[sortDescriptor1 release];

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                  managedObjectContext:context
                                                                  sectionNameKeyPath:nil
                                                                           cacheName:nil];
self.fetchedResultsController.delegate = self;

[request release];

NSError *anyError = nil;

if(![_fetchedResultsController performFetch:&anyError])
{
NSLog(@"error fetching:%@", anyError);
} 

return _fetchedResultsController;
}

多谢你们。

4

1 回答 1

0

您必须使用具有适当设置NSFetchedResultsController的新创建一个新的:NSFetchRequestNSPredicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date == %@)", dateToFilterFor];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Expense" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];

// ...

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"SomeCacheName"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

不要忘记[self.tableView reloadData];在分配新的 FRC 后打电话。

编辑:您可以将谓词NSFetchRequest分配给然后分配给 fetchedResultsController。您可以将谓词视为过滤器。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date == %@)", dateToFilterFor];

如果您通过调用将其添加到获取请求中,则[fetchRequest setPredicate:predicate];告诉获取的请求仅获取NSManagedObject与您在谓词中提供的日期匹配的日期属性的结果。这正是您想要的。

因此,如果您有一个在用户选择日期后调用的方法,您可以像这样修改它:

- (void)userDidSelectDate:(NSDate *)date
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];


    //Here you create the predicate that filters the results to only show the ones with the selected date
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date == %@)", date];
    [fetchRequest setPredicate:predicate];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
   aFetchedResultsController.delegate = self;

   //Here you replace the old FRC by this newly created
   self.fetchedResultsController = aFetchedResultsController;


   NSError *error = nil;
   if (![self.fetchedResultsController performFetch:&error]) {
     // Replace this implementation with code to handle the error appropriately.
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
   }

   //Finally you tell the tableView to reload it's data, it will then ask your NEW FRC for the new data
   [self.tableView reloadData];


}

请注意,如果您不使用 ARC(您应该这样做),则必须适当地释放分配的对象。

于 2012-10-28T11:24:28.573 回答