我的核心数据实现中有一个我似乎无法理解的错误,并且我需要一些提示,指出应该在哪里寻找解决方法。
长话短说,我有一个UITableView
由NSFetchedResultsController
填充。我希望用户能够更改数据的排序选项,所以我给他们提供了一个选择器,该选择器会将基础fetchedResultsController
更改为不同的预设配置。我可以在不同的fetchedResultsControllers
之间来回切换,没有任何问题。我可以添加和删除数据,从不发生任何崩溃,没问题。但是,在fetchedResultController
配置的2个(6个中,总是2个)中,添加到数据库的项目不会添加到表视图中。表格视图中的项目一旦被编辑就会消失。
这是我要重现该错误的步骤:
将排序设置为有效的配置
将新项目添加到数据库(此时controllerWillChangeContent
触发)
更改为无效的配置
将新项目添加到数据库(controllerWillChangeContent
不触发)
切换回工作配置
现在,添加的项目在tableView
中可见
切换回非工作配置
该项目现在在tableView
中可见
编辑项目(触发了controllerWillChangeContent
,但是触发了类型为controller:DidChangeObject:
而不是NSFetchedResultsChangeDelete
的NSFetchedResultsChangeUpdate
)
更改回工作配置,该项目将更改并再次可见。
我对此事不知所措。我完全没有主意。这两个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都会自动插入初始值。