2010-07-29 69 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

相關問題