当NSPredicate设置时,UITableView不刷新 [英] UITableView doesn't refresh when NSPredicate set

查看:279
本文介绍了当NSPredicate设置时,UITableView不刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前言:我尝试了 [self.tableview reloadData] 。我的应用程序不会崩溃,但它不刷新,无论。



我试图在一个 TableViewController 上显示两组结果,具体取决于 NSPredicate 设置。我试图找到一个行话的免费答案我如何更新一个 UITableViewController 一旦一个谓词设置。



我的数据正确显示视图最初加载的时间。我的谓词设置正确,所有的日志语句我抛出的返回值...但是没有什么发生,当它设置。



我知道这是一个非常愚蠢的问题,但我太蠢了。我发现的每个答案涉及到一个 UISearchBar ,不推荐使用的方法,或者是一个答案的片段等。



我想显示的内容:



1)显示所有内容的vanilla fetchRequest:在我的managedObjectContext中的一切都在我的 viewDidLoad w / o an NSPredicate 中设置。



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



On MyTableViewController ,我有一个popover,当我点击一个UIBarButtonItem在MyTableViewController实例化。在弹出窗口中,我在MyTableViewController上设置一个谓词。



基本上,我想切换显示的内容,显示切换是由我的变量是nil显示)或过滤(变量设置谓词)。



我是第一个或最蠢的人尝试这个软件工程专长。我会打赌后者,因为我看到这是一个最终用户多少次。 如果您知道我在做什么,我们非常感谢您的回复。非常感谢您阅读。



我有两个实体: PointOfInterest LocationCategory 。我有一个 UIBarButton 触发一个弹出窗口,其中 MyTableViewController 是一个委托。点击弹出窗口在 MyTableViewController 上设置 selectedCategory 属性:

  //这由PopoverTableViewController设置
@property(nonatomic,strong)LocationCategory * selectedCategory;

//这是在`MyTableViewController`上设置的
@property(nonatomic,strong)NSPredicate * searchPredicate;

属性在 MyTableViewController 上正确设置。我试图使用 selectedCategory 对象作为谓词显示过滤列表的pointOfInterest对象的基础。我从这个 TVC 中省去了样板代码,但是我有 TVC 上的tableView委托方法。 / p>

我想我需要设置我的 fetchedResultsController 为nil并重新赋予它在我的 refreshTableViewController 方法。它不会崩溃,但它不工作。



这是 viewDidLoad MyTableViewController

   - (void)viewDidLoad {
[super viewDidLoad] ;

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

//取消注释以下行以保留演示文稿之间的选择。
// self.clearsSelectionOnViewWillAppear = NO;

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

//初始化获取请求
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@PointOfInterest];

//添加排序描述符
[fetchRequest setSortDescriptors:@ [[NSSortDescriptor sortDescriptorWithKey:@nameascending:YES]]];

//初始化获取的结果控制器
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

//配置fetchedResultsController
[self.fetchedResultsController setDelegate:self];

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

if(错误){
NSLog(@无法执行提取);
NSLog(@%@,%@,error,error.localizedDescription);
}

//设置一个观察者监听`selectedCategory`的设置
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshTableViewController :) name :@CategorySelectedobject:nil];
}

一旦我的 selectedCategory 设置,我有以下方法设置运行。它不会崩溃,但它不刷新 MyTableViewController 。我怀疑我在这里有一个小错误,但我不知道我做错了什么。

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

// Nuke在viewDidLoad
中加载的缓存[NSFetchedResultsController deleteCacheWithName:@PointOfInterest];

//在viewDidLoad中调用fetchedResultsController alloc / inited
self.fetchedResultsController = nil;

//分配一个新的fetchRequest
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];

//设置实体
NSEntityDescription * entity = [NSEntityDescription entityForName:@PointOfInterestinManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

//添加排序描述符
[fetchRequest setSortDescriptors:@ [[NSSortDescriptor sortDescriptorWithKey:@nameascending:YES]]];

//重新获取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);

//使用谓词
[fetchRequest setPredicate:self.searchPredicate]来执行fetchRequest;

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

if(错误){
NSLog(@无法执行提取);
NSLog(@%@,%@,error,error.localizedDescription);
}
[self.tableView reloadData];


}
}

仅仅为了完整性'缘,这里是我的 PointOfInterest & LocationCategory classs:

  #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


解决方案



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

  @synthesize fetchedResultsController = _fetchedResultsController; 

正如我预期的,我错过了一些惊人的愚蠢 - 和 !!



我在Ray Wenderlich的网站上看到这篇文章,我注意到它在实现中有这行,但我没有。我从来没有遇到过需要使用 @synthesize ,我已经看到在别的地方,你几乎从不需要它等,好吧,结果,你做!



http://www.raywenderlich.com/14742/core-data-on-ios-5-tutorial-how-to-work-with-relations-and-谓词



StackOverflow上的这篇文章介绍了 @synthesize 的基本知识。



@synthesize到底是做什么的? p>

Preface: I tried [self.tableview reloadData]. My app doesn't crash, but it doesn't refresh, either.

I'm trying to display 2 sets of results on one TableViewController depending upon whether an NSPredicate is set. I'm trying to find a jargon free answer how I can update a UITableViewController once a predicate is set.

My data displays properly the when the view initially loads. My predicate sets properly, all the log statements I've thrown in return values...but nothing happens when it's set.

I know this is a startlingly stupid question, but I'm too dumb figure it out. Every answer I've found involves a UISearchBar, deprecated methods, or is a snippet of an answer, etc.

What I'd like to display:

1) A vanilla fetchRequest that displays everything--this works: everything in my managedObjectContext which is set up in my viewDidLoad w/o an NSPredicate.

2) Once I set an NSPredicate, I'd like to update the tableView--This doesn't crash, but it doesn't update the tableView

On MyTableViewController, I have a popover which instantiates when I click a UIBarButtonItem on MyTableViewController. On the popover, I set a predicate on MyTableViewController.

Basically, I'd like to toggle what's displayed and that display toggle is driven by whether my variable is nil (everything displays) or filtered (variable sets a predicate).

I'm either the first or the dumbest person to attempt this feat of software engineering. I'll wager the latter, given how many times I've seen this as an end-user. If you know what I'm doing wrong, I'd be grateful to hear from you. Thank you for reading.

I have two entities: PointOfInterest and LocationCategory. I have a UIBarButton that triggers a popover of which MyTableViewController is a delegate. Clicking on the popover sets the selectedCategory property on MyTableViewController.:

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

// This is set on `MyTableViewController`
@property (nonatomic, strong) NSPredicate *searchPredicate;

The property gets set correctly on MyTableViewController. I'm trying to use the selectedCategory object as the basis for a predicate to display "filtered" list of 'pointOfInterest' objects. I left out the boilerplate code from this TVC, but I've got the tableView delegate methods on the TVC.

I think I need to set my fetchedResultsController to nil and reinstantiate it w/ a predicate in my refreshTableViewController method. It doesn't crash, but it doesn't work, either.

Here's the viewDidLoad of 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];    
}

Once my selectedCategory is set, I have the following method set to run. It doesn't crash, but it doesn't refresh MyTableViewController. I suspect I've got a minor error here, but I'm not sure what I'm doing wrong.

- (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];        


    }
}

Just for completeness' sake, here's my PointOfInterest & LocationCategory classs:

#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

解决方案

I figured it out:

I added this to my implementation file on MyTableViewController:

@synthesize fetchedResultsController = _fetchedResultsController;

As I expected, I was missing something startlingly stupid--and I was **RIGHT!!

I read this post on Ray Wenderlich's website and I noticed it had that line in the implementation, but I didn't. I've never encountered the need to use @synthesize and I've seen mentions elsewhere that "you almost never need it", etc. Well, turns out, you do!

http://www.raywenderlich.com/14742/core-data-on-ios-5-tutorial-how-to-work-with-relations-and-predicates

This post on StackOverflow covers the basics of @synthesize.

What exactly does @synthesize do?

这篇关于当NSPredicate设置时,UITableView不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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