Ios UITableView没有';当NSPredicate集合时,不刷新

Ios UITableView没有';当NSPredicate集合时,不刷新,ios,objective-c,uitableview,core-data,nspredicate,Ios,Objective C,Uitableview,Core Data,Nspredicate,前言:我尝试了[self.tableview重载数据]。我的应用程序没有崩溃,但也不会刷新 我试图在一个TableViewController上显示两组结果,具体取决于是否设置了NSPredicate。我正在试图找到一个不使用行话的答案,即一旦设置了谓词,如何更新UITableViewController “我的数据”在视图最初加载时正确显示。我的谓词设置正确,我抛出的所有日志语句都返回值……但设置后什么也不会发生 我知道这是一个愚蠢得惊人的问题,但我太笨了,弄不明白。我找到的每个答案都包含一个

前言:我尝试了
[self.tableview重载数据]
。我的应用程序没有崩溃,但也不会刷新

我试图在一个
TableViewController
上显示两组结果,具体取决于是否设置了
NSPredicate
。我正在试图找到一个不使用行话的答案,即一旦设置了谓词,如何更新
UITableViewController

“我的数据”在视图最初加载时正确显示。我的谓词设置正确,我抛出的所有日志语句都返回值……但设置后什么也不会发生

我知道这是一个愚蠢得惊人的问题,但我太笨了,弄不明白。我找到的每个答案都包含一个
UISearchBar
、不推荐的方法,或者是答案的一个片段,等等

我想显示的内容:

1) 一个普通的fetchRequest,显示所有内容——它的工作原理是:我的managedObjectContext中的所有内容,它是在我的
viewDidLoad中设置的,没有
NSPredicate

2) 一旦我设置了一个
NSPredicate
,我想更新
tableView
——这不会崩溃,但不会更新
tableView

MyTableViewController
上,我有一个弹出窗口,当我在MyTableViewController上单击UIBarButtonItem时,它会实例化。在popover上,我在MyTableViewController上设置了一个谓词

基本上,我想切换显示的内容,并且显示切换由变量是nil(所有显示)还是filtered(变量设置谓词)驱动

我不是第一个或是最愚蠢的人尝试软件工程这一壮举。我敢打赌是后者,因为我作为最终用户已经看过多少次了如果您知道我做错了什么,我将非常感谢您的来信。谢谢您的阅读

我有两个实体:
PointOfInterest
LocationCategory
。我有一个
UIBarButton
,它触发一个popover,其中
MyTableViewController
是一个委托。单击弹出框设置
MyTableViewController
上的
selectedCategory
属性:

// This gets set by PopoverTableViewController    
@property (nonatomic, strong) LocationCategory *selectedCategory;     

// This is set on `MyTableViewController`
@property (nonatomic, strong) NSPredicate *searchPredicate;
MyTableViewController
上正确设置属性。我试图使用
selectedCategory
对象作为谓词的基础,以显示“感兴趣点”对象的“过滤”列表。我省略了这个
TVC
中的样板代码,但是在
TVC
中有tableView委托方法

我想我需要将
fetchedResultsController
设置为nil,并在
refreshtTableViewController
方法中使用谓词重新实例化它。它没有崩溃,但也不起作用

以下是
MyTableViewController
viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    self.managedObjectContext = appDelegate.managedObjectContext;

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    NSLog(@"savedPOI managedObjectContext is %@", self.managedObjectContext);

    // Initialize fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:@"PointOfInterest"];

    // Add sort descriptors
    [fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];

    // Initialize Fetched Results Controller
    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    // Configure a fetchedResultsController
    [self.fetchedResultsController setDelegate:self];

    // Perform fetch
    NSError *error = nil;
    [self.fetchedResultsController performFetch:&error];

    if (error) {
        NSLog(@"Unable to perform fetch");
        NSLog(@"%@, %@", error, error.localizedDescription);
    }

    // This sets up an observer that listens for when `selectedCategory` is set
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(refreshTableViewController:) name:@"CategorySelected" object:nil];    
}
@synthesize fetchedResultsController = _fetchedResultsController;
一旦设置了my
selectedCategory
,我就可以运行以下方法。它不会崩溃,但不会刷新
MyTableViewController
。我怀疑我这里有一个小错误,但我不确定我做错了什么

- (void)refreshTableViewController:(NSNotification *)notification {
    if ([[notification name]isEqualToString:@"CategorySelected"]) {
        NSLog(@"NSNotification on SavedPOITableViewController's self.selectedCategory is %@", self.selectedCategory.categoryName);

        // Nuke the cache that was loaded in viewDidLoad
        [NSFetchedResultsController deleteCacheWithName:@"PointOfInterest"];

        // Nuke the fetchedResultsController alloc/inited in viewDidLoad
        self.fetchedResultsController = nil;

        // Alloc init a new fetchRequest
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

        // Set the entity
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"PointOfInterest" inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entity];

        // Add sort descriptors
        [fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];

        // Reinstantiate the fetchedResultsController
            self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

        NSString *predicateString = self.selectedCategory.categoryName;
        NSLog(@"predicateString is %@", predicateString);

        self.searchPredicate = [NSPredicate predicateWithFormat:@"locationCategory.categoryName == %@", predicateString];
        NSLog(@"self.searchPredicate in refreshTableViewController is %@", predicateString);

        // Do the fetchRequest with the predicate
        [fetchRequest setPredicate:self.searchPredicate];

        // Perform fetch
        NSError *error = nil;
        [self.fetchedResultsController performFetch:&error];

        if (error) {
            NSLog(@"Unable to perform fetch");
            NSLog(@"%@, %@", error, error.localizedDescription);
        }
        [self.tableView reloadData];        


    }
}
为了完整起见,这里是我的
兴趣点
位置类别
类别:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class LocationCategory;

@interface PointOfInterest : NSManagedObject

@property (nonatomic, retain) NSString * note;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSNumber * latitude;
@property (nonatomic, retain) NSNumber * longitude;
@property (nonatomic, retain) NSString * phoneNumber;
@property (nonatomic, retain) NSString * url;
@property (nonatomic, retain) LocationCategory *locationCategory;

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class PointOfInterest;

@interface LocationCategory : NSManagedObject

@property (nonatomic, retain) id categoryColor;
@property (nonatomic, retain) NSString * categoryName;
@property (nonatomic, retain) NSSet *pointOfInterest;
@end
#导入
#进口
@类别位置类别;
@感兴趣的接口点:NSManagedObject
@属性(非原子,保留)NSString*注释;
@属性(非原子,保留)NSString*名称;
@属性(非原子,保留)NSString*地址;
@属性(非原子,保留)NSNumber*纬度;
@属性(非原子,保留)NSNumber*经度;
@属性(非原子,保留)NSString*phoneNumber;
@属性(非原子,保留)NSString*url;
@属性(非原子,保留)位置类别*位置类别;
#进口
#进口
@兴趣点类别;
@接口位置类别:NSManagedObject
@属性(非原子,保留)id类别颜色;
@属性(非原子,保留)NSString*categoryName;
@属性(非原子,保留)NSSet*兴趣点;
@结束
我想出来了:

我在
MyTableViewController
上将其添加到我的实现文件中:

- (void)viewDidLoad {
    [super viewDidLoad];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    self.managedObjectContext = appDelegate.managedObjectContext;

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    NSLog(@"savedPOI managedObjectContext is %@", self.managedObjectContext);

    // Initialize fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:@"PointOfInterest"];

    // Add sort descriptors
    [fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];

    // Initialize Fetched Results Controller
    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    // Configure a fetchedResultsController
    [self.fetchedResultsController setDelegate:self];

    // Perform fetch
    NSError *error = nil;
    [self.fetchedResultsController performFetch:&error];

    if (error) {
        NSLog(@"Unable to perform fetch");
        NSLog(@"%@, %@", error, error.localizedDescription);
    }

    // This sets up an observer that listens for when `selectedCategory` is set
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(refreshTableViewController:) name:@"CategorySelected" object:nil];    
}
@synthesize fetchedResultsController = _fetchedResultsController;
正如我预料的那样,我错过了一些令人吃惊的愚蠢的事情,我是**对的

我在Ray Wenderlich的网站上读到这篇文章,我注意到它在实现中有这一行,但我没有。我从来没有遇到过使用
@synthesis
的需要,我也看到其他地方提到“你几乎从来都不需要它”,等等。事实证明,你需要

这篇关于StackOverflow的文章涵盖了
@synthesis
的基础知识


是否正在更新tableview数据源?请提供一些有关如何填充tableview的相关代码,特别是
cellforrowatinexpath:
delegate方法body.No。我有
fetchedResultsController
,它在标题中声明并在
viewDidLoad
中实例化。我所要做的就是在选择了类别时更新
fetchedResultsController
。但是你在哪里将更新的结果绑定到表视图?!我不明白你的问题。你的
refreshTableViewController:
方法实际上什么都不做。问问自己:“简单地创建一个
NSFetchRequest
的实例,怎么会导致fetchedresults控制器中的任何更改,更不用说在表视图中了?”