NSFetchedResultsController fetch请求 - 更新谓词和UITableView [英] NSFetchedResultsController fetch request - updating predicate and UITableView

查看:144
本文介绍了NSFetchedResultsController fetch请求 - 更新谓词和UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的iPhone Core Data应用程序中,我在主 - 详细视图设置中配置它。



主视图是一个UITableView, $ c> List 实体。 List实体与 Task 实体(称为tasks)具有一对多关系,Task实体与列表 c>调用列表。



当在列表中选择列表主视图,我想要详细视图(另一个UITableView)列出对应于 List 对象的任务对象。我到目前为止做的是这样:



在细节视图控制器中,我已经为 List object:



@property(nonatomic,retain)List * list;



然后在主视图控制器中,当选择列表时,使用此表视图委托方法设置详细视图控制器的 list 属性:

   - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject * selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
detailViewController.list =(List *)selectedObject;
}

然后,我覆盖了列表在详细视图控制器中的属性:

   - (void)setList: )newList 
{
if(list!= newList){
[list release];
list = [newList retain];

NSPredicate * newPredicate = [NSPredicate predicateWithFormat:@(list ==%@),list];
[NSFetchedResultsController deleteCacheWithName:@Root];
[[[self fetchedResultsController] fetchRequest] setPredicate:newPredicate];

NSError * error = nil;
if(![[self fetchedResultsController] performFetch:& error]){
NSLog(@未解决的错误%@,%@,错误,[错误userInfo]);
abort();
}
}
}

在获取的结果上设置一个谓词以过滤出对象,以便我只获得属于所选 List 对象的那些对象。详细视图控制器的fetchedResultsController getter如下所示:

   - (NSFetchedResultsController *)fetchedResultsController {
if(fetchedResultsController == nil){
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@TaskinManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate * predicate = [NSPredicate predicateWithFormat:@FALSEPREDICATE];
[fetchRequest setPredicate:predicate];

NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@nameascending:YES];
NSArray * sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,nil];

[fetchRequest setSortDescriptors:sortDescriptors];

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

[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
}

return fetchedResultsController;
}

它与Core Data项目模板中的默认值几乎没有变化,做的是添加一个总是返回false的谓词,原因是当没有列表选择我不想要任何项目显示在细节视图中(如果选择列表,谓词在setter中更改为列表属性)。



但是,当我选择列表项时,没有什么真正发生。表视图中没有任何内容更改,它保持为空。

感谢

解决方案

/ div>

您不需要为任务列表设置 NSFetchedResultsController 。因为你是传递List实体,你可以只要求List实体的任务:

  NSSet * tasks = [[ self list] valueForKey:@tasks]; 
NSSortDescriptor * sort = ...;
NSArray * sorted = [[tasks allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
[self setTasks:sorted];

然后让 UITableviewDatasource tasks 数组。


In my iPhone Core Data app I have it configured in a master-detail view setup.

The master view is a UITableView that lists objects of the List entity. The List entity has a to-many relationship with the Task entity (called "tasks"), and the Task entity has an inverse to-one relationship with List called "list".

When a List object is selected in the master view, I want the detail view (another UITableView) to list the Task objects that correspond to that List object. What I've done so far is this:

In the detail view controller I've declared a property for a List object:

@property (nonatomic, retain) List *list;

Then in the master view controller I use this table view delegate method to set the list property of the detail view controller when a list is selected:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    detailViewController.list = (List*)selectedObject; 
}

Then, I've overriden the setter for the list property in the detail view controller like this:

- (void)setList:(List*)newList
{
    if (list != newList) {
        [list release];
        list = [newList retain];

        NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"(list == %@)", list];
        [NSFetchedResultsController deleteCacheWithName:@"Root"];
        [[[self fetchedResultsController] fetchRequest] setPredicate:newPredicate];

        NSError *error = nil;
        if (![[self fetchedResultsController] performFetch:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }       
    }
}

What I'm doing here is setting a predicate on the fetched results to filter out the objects so that I only get the ones that belong to the selected List object. The fetchedResultsController getter for the detail view controller looks like this:

- (NSFetchedResultsController *)fetchedResultsController {
    if (fetchedResultsController == nil) {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];
    [fetchRequest setPredicate:predicate];

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

        [fetchRequest setSortDescriptors:sortDescriptors];

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

        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptors release];
    }

    return fetchedResultsController;
}    

Its almost unchanged from the default in the Core Data project template, the change I made is to add a predicate that always returns false, the reason being that when there is no List selected I don't want any items to be displayed in the detail view (if a list is selected the predicate is changed in the setter for the list property).

However, when I select a list item, nothing really happens. Nothing in the table view changes, it stays empty. I'm sure my logic is flawed in several places, advice is appreciated

Thanks

解决方案

You don't need to set up a NSFetchedResultsController for your task list. Since you are passing in the List entity, you can just ask the List entity for the tasks:

NSSet *tasks = [[self list] valueForKey:@"tasks"];
NSSortDescriptor *sort = ...;
NSArray *sorted = [[tasks allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
[self setTasks:sorted];

Then have the UITableviewDatasource methods run off of that tasks array.

这篇关于NSFetchedResultsController fetch请求 - 更新谓词和UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆