我有一个UITableViewController,它由NSFetchedResultsController填充。我的CoreData实体有一个名为" submitter_id"的属性。根据我的控制器的初始化方式,我想获取与给定的submitter_id匹配的记录,或者哪个DON&t; T匹配所述的submitter_id。 "匹配"案件工作正常,但我遇到的问题是"没有匹配"案件。我的sqlite数据库是正确的,但我在TableView中得到了额外的空行。
在下面的输出中,我从Core Data获得了正确的3条记录,但是NSFetchedResultsController(或某人)在我的TableView中添加了34个空行。注意:空行数遵循一个模式,这可能是一个线索:如果我删除应用程序并从头开始,我首先得到17个空行+3个好行。当我第二次运行时,我得到34个空行+3个好行。从那时起,它稳定在34个空行。有趣的是,我的测试数据集中有17条记录。
2011-03-25 15:35:17.256 test[54095:207] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZDELETED, t0.ZDESCRIPTION, t0.ZITEMID, t0.ZICON, t0.ZAVG, t0.ZNAME, t0.ZCREATIONDATE, t0.ZIMAGE, t0.ZSUBMITTERID, t0.ZUSER FROM ZITEM t0 WHERE t0.ZSUBMITTERID <> ? ORDER BY t0.ZNAME DESC
2011-03-25 15:35:17.257 test[54095:207] CoreData: details: SQLite bind[0] = 32
2011-03-25 15:35:17.258 test[54095:207] CoreData: annotation: sql connection fetch time: 0.0017s
2011-03-25 15:35:17.258 test[54095:207] CoreData: annotation: fetch using <NSSQLiteStatement: 0x5f920f0> returned 3 rows with values: (
"Plastic ballpoint",
"Walmart readers",
Blue
)
2011-03-25 15:35:17.263 test[54095:207] CoreData: annotation: total fetch execution time: 0.0071s for 3 rows.
2011-03-25 15:35:17.264 test[54095:207] numberOfSectionsInTableView: 1
2011-03-25 15:35:17.264 test[54095:207] numberOfRowsInSection 0: 37
2011-03-25 15:35:17.265 test[54095:207] indexPath 0
2011-03-25 15:35:17.268 test[54095:207] name: pen
2011-03-25 15:35:17.268 test[54095:207] indexPath 1
2011-03-25 15:35:17.269 test[54095:207] name: glasses
2011-03-25 15:35:17.269 test[54095:207] indexPath 2
2011-03-25 15:35:17.270 test[54095:207] name: checkbook
2011-03-25 15:35:17.270 test[54095:207] indexPath 3
2011-03-25 15:35:17.272 test[54095:207] name: (null)
2011-03-25 15:35:17.273 test[54095:207] indexPath 4
2011-03-25 15:35:17.275 test[54095:207] name: (null)
2011-03-25 15:35:17.275 test[54095:207] indexPath 5
2011-03-25 15:35:17.275 test[54095:207] name: (null)
2011-03-25 15:35:17.278 test[54095:207] indexPath 6
2011-03-25 15:35:17.279 test[54095:207] name: (null)
2011-03-25 15:35:17.279 test[54095:207] indexPath 7
2011-03-25 15:35:17.280 test[54095:207] name: (null)
2011-03-25 15:35:17.281 test[54095:207] indexPath 8
2011-03-25 15:35:17.281 test[54095:207] name: (null)
这是我设置NSFetchedResultsController的代码:
- (BOOL) setupFRC
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO]];
NSPredicate *p1;
if (self.listType == MY_ITEMS_LIST) {
p1 = [NSPredicate predicateWithFormat:@"submitterID == %qu", appDelegate.user.userID];
}
else {
p1 = [NSPredicate predicateWithFormat:@"submitterID != %qu", appDelegate.user.userID];
}
request.predicate = p1;
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
frc.delegate = self;
self.fetchedResultsController = frc;
[frc release];
[request release];
return YES;
}
- (void)performFetchForTableView
{
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
if (error) {
NSLog(@"[CoreDataTableViewController performFetchForTableView:] %@ (%@)", [error localizedDescription], [error localizedFailureReason]);
}
[self.tableView reloadData];
}
我在这里格式化单元格:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForManagedObject:(NSManagedObject *)managedObject
{
static NSString *CellIdentifier;
if (self.listType == MY_ITEMS_LIST) {
CellIdentifier = @"RSMyItemCell";
}
else {
CellIdentifier = @"RSTBDItemCell";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
CDItem *item = (CDItem *)managedObject;
cell.textLabel.text = item.name;
cell.detailTextLabel.text = item.description;
NSLog(@"name: %@",item.name);
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
NSInteger n = [sectionInfo numberOfObjects];
NSLog(@"numberOfRowsInSection %d: %d",section,n);
return n;
}
我确定我错过了一些东西,但我对如何进一步调试感到困惑。有人见过这个吗?如果您想查看其他任何代码段,请与我们联系。
谢谢!
STU
答案 0 :(得分:0)
有时候只需要清晰的头脑即可。周末回来后,我看到了问题所在。供您参考,以下是发生的事情:
在应用启动时,我使用从服务器下载的项目列表更新CoreData DB。在尝试添加之前,我检查CoreData中是否已存在给定项目。错误是我打电话
[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
在执行我的存在检查之前。这导致创建的实体没有相应的托管对象。即使CoreData将正确的数据集返回给NSFetchedResultsController,控制器也必须使用实体计数来确定[sectionInfo numberOfObjects]
;
在任何情况下,在“不存在”子句(发生insertNewObjectForEntityForName
)内移动addObject
调用可以解决问题。
谢谢,
STU