【发布时间】:2011-05-18 16:15:46
【问题描述】:
我的核心数据实现中有一个我似乎无法控制的错误,我需要一些提示来了解如何修复它。
长话短说,我有一个 UITableView 被 NSFetchedResultsController 填充。我希望我的用户能够更改数据的排序选项,所以我给他们一个选择器,它将底层的fetchedResultsController 更改为不同的预设配置。我可以在不同的fetchedResultsControllers 之间来回切换,没有任何问题。我可以添加和删除数据,从来没有遇到任何崩溃,没问题。但是,在fetchedResultController 配置中的 2 个(共 6 个,并且始终相同的 2 个)上,添加到数据库的项目不会添加到 tableview。并且 tableview 中的项目一旦编辑就会消失。
以下是我重现错误的步骤:
- 将排序设置为有效的配置
- 向数据库添加一个新项目(此时
controllerWillChangeContent触发) - 更改为不起作用的配置
- 向数据库添加新项目(
controllerWillChangeContent不会触发) - 切换回工作配置
- 添加的项目现在在
tableView中可见 - 切换回非工作配置
- 该项目现在在
tableView中可见 - 编辑项目(
controllerWillChangeContent被触发,但controller:DidChangeObject:被触发,类型为NSFetchedResultsChangeDelete而不是NSFetchedResultsChangeUpdate) - 改回工作配置,项目已更改并再次可见。
我对这件事束手无策。我完全没有想法。这 2 个 fetchedResultsControllers 的创建方式与其他 4 个的创建方式几乎没有区别。 任何可以提供的帮助将不胜感激。
--编辑--
对此仍有一些问题。重申对 TechZen 问题的一些答案:
- 我的所有属性都没有设置为瞬态值
- 目前我使用的是平面模型。它是具有直接属性的单个实体。没有任何关系。
- 问题仍然存在,缓存设置为
nil - 我在每次更改之前将旧的
frc的代表设置为nil,并在切换结束时将新的frc的代表设置为self。这在所有 6 个frcs 中都是一致的 - 我将释放旧的
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 委托方法相关的代码,以及您正在使用的数据模型吗?
-
@unforgiven 在问题中添加了一堆代码。如果您还有其他想看的,请告诉我。
-
“工作”和“位置”属性都是可选的。您在其中一个损坏的配置中添加的新项目实际上是否包含这些属性的值?可能没有将项目添加到表中,因为由于它的属性值和您的 NSFetchedResultsController 设置,根本没有获取它。出于同样的原因,也可能是一旦编辑后,某个项目就会从表格中消失(因为它在编辑后不再属于表格)。
-
你是我的英雄。那解决了它。提交答案,以便我奖励您赏金。有没有办法将 Null 值设置为这些属性的默认值?
-
没关系。保存对象时,只需在这些属性中添加一个空字符串,现在一切都很好。非常感谢。
标签: iphone uitableview core-data nsfetchedresultscontroller