我的核心数据实现中有一个我似乎无法理解的错误,并且我需要一些提示,指出应该在哪里寻找解决方法。

长话短说,我有一个UITableViewNSFetchedResultsController填充。我希望用户能够更改数据的排序选项,所以我给他们提供了一个选择器,该选择器会将基础fetchedResultsController更改为不同的预设配置。我可以在不同的fetchedResultsControllers之间来回切换,没有任何问题。我可以添加和删除数据,从不发生任何崩溃,没问题。但是,在fetchedResultController配置的2个(6个中,总是2个)中,添加到数据库的项目不会添加到表视图中。表格视图中的项目一旦被编辑就会消失。

这是我要重现该错误的步骤:


将排序设置为有效的配置
将新项目添加到数据库(此时controllerWillChangeContent触发)
更改为无效的配置
将新项目添加到数据库(controllerWillChangeContent不触发)
切换回工作配置
现在,添加的项目在tableView中可见
切换回非工作配置
该项目现在在tableView中可见
编辑项目(触发了controllerWillChangeContent,但是触发了类型为controller:DidChangeObject:而不是NSFetchedResultsChangeDeleteNSFetchedResultsChangeUpdate
更改回工作配置,该项目将更改并再次可见。


我对此事不知所措。我完全没有主意。这两个fetchedResultsControllers的创建方式与其他四个nil几乎没有区别。可以提供的任何帮助将不胜感激。

- 编辑 -

仍然有一些问题。重申对TechZen问题的一些答案:


我的所有属性均未设置为瞬态值
我目前正在使用平面模型。它是具有直接属性的单个实体。没有关系。
缓存设置为frc时,问题仍然存在
我将每次更改之前将旧nil的代理设置为frc,并在切换结束时将新self的代理设置为frc。这在所有6个frc中都是一致的
每当用户切换到其他排序选项时,我都会发布旧的frc并创建一个新的。


对于那些感兴趣的人,我用来切换的代码位于要点here

-编辑2-

为任何可以向我指出正确方向的人提供悬赏。

-编辑3-

根据要求,以下是我的委托方法的代码:

-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}

-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch (type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

    }
}

-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
    switch (type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeUpdate:
            if (!self.searchIsActive) {
                [self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            } else {
                [self.searchDisplayController.searchResultsTableView reloadData];
            }
            break;
        case NSFetchedResultsChangeMove:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];

}


信息得到了我的数据模型:

// Person.h
#import <CoreData/CoreData.h>
@interface Person :  NSManagedObject
{
}

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * company;
@property (nonatomic, retain) NSString * comments;
@property (nonatomic, retain) NSString * job;
@property (nonatomic, retain) NSDate * logDate;
@property (nonatomic, retain) NSString * location;
@property (nonatomic, retain) NSNumber * rating;
@property (nonatomic, retain) NSString * imagePath;
@property (nonatomic, retain) NSString * thumbPath;

@end

// Person.m
#import "Person.h"

@implementation Person

@dynamic name;
@dynamic company;
@dynamic comments;
@dynamic job;
@dynamic logDate;
@dynamic location;
@dynamic rating;
@dynamic imagePath;
@dynamic thumbPath;

@end


有关数据模型的信息:

Entity: Person
    Property: comments
        kind: attribute
        type: string
        optional: YES
    Property: name
        kind: attribute
        type: string
        optional: NO
    Property: rating
        kind: attribute
        kind: Int 16
        optional: YES
        min value: 0
        max value: 5
    Property: job
        kind: attribute
        kind: string
        optional: YES
    Property: company
        kind: attribute
        kind: string
        optional: YES
    Property: location
        kind: attribute
        kind: string
        optional: YES
    Property: imagePath
        kind: attribute
        kind: string
        optional: YES
    Property: thumbPath
        kind: attribute
        kind: string
        optional: YES
    Property: logDate
        kind: attribute
        kind: date
        optional: YES


没什么特别的。

最佳答案

我根据要求将此评论重新发布为答案。

“作业”和“位置”属性都是可选的。您在一种损坏的配置中添加的新项目是否实际上包含这些属性的值?可能某项未添加到表中,因为由于其属性值和您的NSFetchedResultsController设置,根本根本不会提取该项。出于相同的原因,可能是项目一旦被编辑,就会从表中消失(因为它在编辑后不再属于表)。

编辑:

要设置不同于nil的初始值,请在您的Core Data Person.m文件中添加以下方法

- (void) awakeFromInsert{
    self.job = @"";
    self.location = @"";
}


这样,每次创建新人员对象时,Core Data都会自动插入初始值。

10-08 02:37