在我的另一个question中,关于在Core Data支持的UITableView中添加插入行,我提到我的NSFetchedResultsController将它提取的每个对象分配到我的UITableView中的一个单独的部分。我认为这只是默认行为,但Marcus S. Zarra说我的控制器配置或我的数据源委托方法可能有问题。我承认,我的代码感觉有点像弗兰肯斯坦,其部分内容来自Apple文档和大量教程。这是我的第一个程序,也是我第一次使用Core Data,所以请保持温和;)
我的表视图控制器的标题如下:
#import <UIKit/UIKit.h>
#import "RubricAppDelegate.h"
@interface ClassList : UITableViewController {
NSMutableArray *classList;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
}
@property(nonatomic,retain) NSMutableArray *classList;
@property(nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property(nonatomic, retain) NSManagedObjectContext *managedObjectContext;
- (IBAction) grade:(id)sender;
@end
我的实现文件包含一堆虚拟测试数据。我包含了以防我使用不正确的方法来实例化Core Data对象。基本上,我想知道我的NSFetchedResultsController是否不将我的对象(在本例中为myClass的实例)返回到单独的部分。如果是这样,我在做什么来创造这个问题?
目前的最终目标是让我能够在桌面顶部添加一个插入单元格(我知道将它置于底部是“标准”,但我喜欢它在应用程序中的外观反过来做)。您会注意到我的-tableView:editingStyleForRowAtIndexPath:
设置要插入的第0部分的单元格样式,但当然我需要弄清楚如何在单元格1而不是单元格0开始myClass.classTitle的列表(这就是我想要的原因)确定是否将每个对象分配给自己的部分是正常的。)
这是我的实施文件:
#import "ClassList.h"
#import "ClassRoster.h"
#import "RubricAppDelegate.h"
#import "Student.h"
#import "myClass.h"
@implementation ClassList
@synthesize classList;
@synthesize fetchedResultsController;
@synthesize managedObjectContext;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.editing = YES;
RubricAppDelegate *appDelegate = (RubricAppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"myClass" inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entity];
//test data
myClass *newClass = (myClass *) [NSEntityDescription insertNewObjectForEntityForName:@"myClass" inManagedObjectContext:managedObjectContext];
newClass.classTitle = @"UFDN 1000";
NSNumber *ID = [NSNumber numberWithInt:1];
newClass.classID = ID;
Student *newStudent = (Student *) [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:managedObjectContext];
newStudent.classID = ID;
newStudent.studentName = @"Andy Albert";
newStudent.studentUsername = @"albera";
[newClass addStudentsObject:newStudent];
newStudent.classID = ID;
newStudent.studentName = @"Bob Dole";
newStudent.studentUsername = @"doleb";
[newClass addStudentsObject:newStudent];
newStudent.classID = ID;
newStudent.studentName = @"Chris Hanson";
newStudent.studentUsername = @"hansoc";
[newClass addStudentsObject:newStudent];
myClass *newClass2 = (myClass *) [NSEntityDescription insertNewObjectForEntityForName:@"myClass" inManagedObjectContext:managedObjectContext];
newClass2.classTitle = @"UFDN 3100";
ID = [NSNumber numberWithInt:2];
newClass2.classID = ID;
newStudent.classID = ID;
newStudent.studentName = @"Danny Boy";
newStudent.studentUsername = @"boyd";
[newClass2 addStudentsObject:newStudent];
newStudent.classID = ID;
newStudent.studentName = @"James Matthews";
newStudent.studentUsername = @"matthj";
[newClass2 addStudentsObject:newStudent];
newStudent.classID = ID;
newStudent.studentName = @"Aaron Todds";
newStudent.studentUsername = @"toddsa";
[newClass2 addStudentsObject:newStudent];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"classID" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
NSError *error;
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"classTitle" cacheName:nil];
[fetchedResultsController performFetch:&error];
UIBarButtonItem *gradeButton = [[UIBarButtonItem alloc]
initWithTitle:@"Grade"
style:UIBarButtonItemStylePlain
target:self
action:@selector(grade:)];
self.navigationItem.rightBarButtonItem = gradeButton;
[gradeButton release];
}
- (IBAction) grade:(id)sender {
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Number of sections = %d", [[fetchedResultsController sections] count]);
return ([[fetchedResultsController sections] count]);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> myClass = [[fetchedResultsController sections] objectAtIndex:section];
NSLog(@"Number of classes = %d", [myClass numberOfObjects]);
return [myClass numberOfObjects];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
myClass *theClass = [fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"Class name is: %@", theClass.classTitle);
cell.textLabel.text = theClass.classTitle;
}
return cell;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0) {
return UITableViewCellEditingStyleInsert;
}
else return UITableViewCellEditingStyleDelete;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
myClass *result = (myClass *)[fetchedResultsController objectAtIndexPath:indexPath];
[managedObjectContext deleteObject:result];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
}
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[classList release];
[super dealloc];
}
@end
我的RubricAppDelegate基本上与Apple文档相同,用于设置Core Data NSManagedObjectContext,NSPersistentStoreCoordinator等。但是,如果您认为可能存在问题,请告诉我,我会发布它。
编辑:我忘了提到两个原因,我知道每个对象被分配到不同的部分。
1)NSLog(@"Number of sections = %d", [[fetchedResultsController sections] count]);
内的-numberOfSectionsInTableView:
返回我拥有的myClass对象的数量。
2)如果我将-numberOfSectionsInTableView:
设置为返回1,我的表格只会显示一个对象,并将其余部分剪掉。
答案 0 :(得分:2)
您有部分,因为您在初始化FRC时通过传递sectionNameKeyPath:
的非Nil值来告诉获取的结果控制器创建它们。
变化:
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"classTitle" cacheName:nil];
...为:
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil cacheName:nil];
......这些部分将会消失。否则,FRC将为商店中classTitle
属性的每个值创建一个部分。如果每个myClass
实例具有不同的classTitle
值,则每个实例在tableview中都有自己的部分。