为啥我必须注释掉我的 NSPredicate 才能让 NSFetchedResultsController 填充 UITableView?

Posted

技术标签:

【中文标题】为啥我必须注释掉我的 NSPredicate 才能让 NSFetchedResultsController 填充 UITableView?【英文标题】:Why do I have to comment out my NSPredicate to have NSFetchedResultsController populate an UITableView?为什么我必须注释掉我的 NSPredicate 才能让 NSFetchedResultsController 填充 UITableView? 【发布时间】:2013-10-25 09:32:25 【问题描述】:

我有一个奇怪的错误:如果我取消注释我的NSPredicate,生成的UITableView 是空的。

我的数据模型如下: 类别 > Feed > 帖子

我正在获取Posts。 Post.feedPostFeedFeed 有一个 rss NString 属性。

代码如下:

    - (NSFetchedResultsController *)fetchedResultsController 

        // Set up the fetched results controller if needed.
        if (_fetchedResultsController == nil) 
            // Create the fetch request for the entity.
            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
            // Edit the entity name as appropriate.
            NSEntityDescription *entity = [NSEntityDescription entityForName:@"Post"
                                                      inManagedObjectContext:_globalMOC];
            [fetchRequest setEntity:entity];

            // Edit the sort key as appropriate.
            NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
            NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
            [fetchRequest setSortDescriptors:sortDescriptors];

            NSPredicate *predicate =[NSPredicate predicateWithFormat:@"feed.rss == %@",  _detailItem.rss];
            [fetchRequest setPredicate:predicate];

            // 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:_globalMOC
                                                  sectionNameKeyPath:nil
                                                           cacheName:nil];
            self.fetchedResultsController = aFetchedResultsController;

            self.fetchedResultsController.delegate = self;

            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. If it is not possible to recover from the error, display an alert
                // panel that instructs the user to quit the application by pressing the Home button.
                //
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            

        

        return _fetchedResultsController;
    

正如我之前所说,如果我取消注释 NSPredicate,我只会看到结果。我试过LIKE===,在%@周围加上双引号和单引号...

顺便说一句,最好直接比较Feed对象...

根据 Apple 的说法,语法可能不是问题,但那又如何呢?

Posts 是在共享相同 PersistentStoreCoordinator 的单独 ManagedObjectController 中创建的。我获得了所需的 Feed 的 objectID,以便将新的 Post 与子 MOC 中对应的 Feed 相关联(否则我会收到关于关联来自不同 MOC 的对象的错误)。

每当子 MOC 通知它发生更改时,我也会适当地将我的 MOC 合并到主线程中。

基本上:如果我有NSLogPosts(注释-NSPredicate),我会看到每个Post 与相关的RSS Feed URL 适合显示的Feed(= detailItem)。

谁能帮帮我?

【问题讨论】:

Strange bug: uncommenting an NSPredicate within an NSFetchedResultsController will empty the UITableView的可能重复 你注意到我也写了那篇文章吗? 【参考方案1】:

如果您的 NSFetchedResultsController 为空白,那么很确定您没有通过 fetch 请求获得任何结果,而且恐怕是因为谓词语句不恰当或没有匹配记录。我想问题是由于存在通配符(对此不太了解) 检查NSPredicate Class Reference 和Predicate Programming Guide 以通过谓词获得准确的结果。

【讨论】:

我不明白,那 NSPredicate 的措辞如何? `` [NSPredicate predicateWithFormat:@"feed.rss == %@", _detailItem.rss]`` 那个 feed.rss 到底是什么? feed.rss和_detailitem.rss的数据类型是什么 你好 Nick,feed.rss 是一个 NSString,_detailItem 也是一个 (Feed *) 对象。我试过带引号和不带引号,也用简单和双等号。我认为问题出在 (Post *) 创建中,在 NSOperation 中声明了自己的 ManagedObjectContext。 我应该在我的 NSPredicate 中使用 SELF.feed.rss,因为我在某处而不是在 Apple 文档网站上阅读?另外,将 .feed 与 _detailItem (两个 (Feed *) 对象)进行比较的实际语法是什么? [NSPredicate predicateWithFormat:@"feed.rss == %@", _detailItem.rss] 对我来说看起来不错。您是否尝试过将值直接传递给谓词?像 [NSPredicate predicateWithFormat:@"feed.rss == rssString"]【参考方案2】:

尤里卡!

问题如下:当我在DetailView 中创建NSFetchedResultsController 时,_detailItemnil

因此,即使在设置 _detailItem 之后,NSPredicate 仍然专注于将我的提要关系与 nil 对象进行比较。

我通过以下方式在didSelectRowAtIndexPath 中刷新NSFetchedResultsController.fetchRequest 中的MasterView 解决了这个问题:

    Feed *feed;
    if (tableView == self.searchDisplayController.searchResultsTableView) 
        feed = [_filteredCategoryArray objectAtIndex:indexPath.row];
     else 
        feed = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    
    self.detailViewController.detailItem = feed;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"feed == %@", feed];
    [self.detailViewController.fetchedResultsController.fetchRequest setPredicate:predicate];

希望这个解决方案可以帮助其他人。

感谢您的帮助,nickAtStack!

【讨论】:

以上是关于为啥我必须注释掉我的 NSPredicate 才能让 NSFetchedResultsController 填充 UITableView?的主要内容,如果未能解决你的问题,请参考以下文章

核心数据 - 为啥我的 NSPredicate 没有产生正确的 SQL 查询?

为啥我必须单击提交按钮 TWICE 才能更新我的 useState() 挂钩?

为啥我必须运行两次“npm install”才能成功安装我的包

如何过滤在 Core Data 中有对象的表视图?

为啥我必须执行两次按钮功能才能使我的逻辑正常工作?

为啥我必须切换纹理单元才能让我的片段着色器识别要使用的纹理?