2010-07-29 58 views
0

在我的另一个question有关在Core Data支持的UITableView中添加插入行的问题,我提到我的NSFetchedResultsController将它提取的每个对象分配给我的UITableView中的一个单独节。我认为这只是默认行为,但Marcus S. Zarra说我的控制器配置或数据源委托方法可能有问题。我承认,我的代码感觉有点像Frankenstein,部分内容来自Apple文档和大量教程。这是我的第一个程序,我的第一次使用的核心数据,所以请温柔;)为什么NSFetchedResultsController将获取的对象分配给多个UITableView节?

我的表视图控制器的标题如下:

#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 

我实现文件包含了一堆虚拟的测试数据。我包括,以防万一我使用不正确的方法来实例化核心数据对象。基本上,我想知道如果我的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是基本相同的苹果文档建立核心数据的NSManagedObjectContext,NSPersistentStoreCoordinator等。但是,如果你认为有可能在那里是一个问题,只是让我知道,我会发布它。

编辑:我忘了提及两个理由,我知道每个对象被分配到不同的部分。

1)NSLog(@"Number of sections = %d", [[fetchedResultsController sections] count]);里面的-numberOfSectionsInTableView:返回我拥有的myClass对象的数量。

2)如果我设置-numberOfSectionsInTableView:返回1,我的表只显示一个对象并将其余部分剪掉。

回答

2

因为您在初始化FRC时通过传递非零值sectionNameKeyPath:来告诉获取的结果控制器创建它们,所以有章节。

变化:

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中都有自己的部分。

+0

这很简单:)感谢TechZen! – Spindler 2010-07-29 17:59:36

相关问题