Почему NSFetchedResultsController назначает извлеченные объекты нескольким разделам UITableView? - PullRequest
0 голосов
/ 29 июля 2010

В другом моем вопросе относительно добавления строки вставки в UITableView, поддерживаемой Core Data, я упомянул, что мой NSFetchedResultsController назначает каждый объект, который он выбирает, отдельному разделу в моем UITableView.Я предположил, что это просто поведение по умолчанию, но Маркус С. Зарра сказал, что может быть что-то не так с моей конфигурацией контроллера или методами делегата источника данных.Признаюсь, мой код немного похож на Франкенштейна с частями, взятыми из документации 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 для вставки, но, конечно, мне нужно выяснить, как начать перечисление myClass.classTitle в ячейке 1 вместо ячейки 0 (поэтому я хочу определить,каждый объект, назначенный для его собственного раздела, является нормальным).

Вот мой файл реализации:

#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и т. д. Однако, если вы считаете, что там может быть проблема, просто дайте мне знать, и я опубликую ее.

Редактировать: я забыл упомянуть две причины, по которым я знаю, что каждый объект назначаетсядругой раздел.

1) NSLog(@"Number of sections = %d", [[fetchedResultsController sections] count]); внутри -numberOfSectionsInTableView: возвращает количество объектов myClass, которые у меня есть.

2) Если я задаю -numberOfSectionsInTableView:, чтобы вернуть 1, моя таблица отображает только один объект ивырезывает все остальное.

1 Ответ

2 голосов
/ 29 июля 2010

У вас есть разделы, потому что вы указываете извлеченному контроллеру результатов создавать их, передавая ненулевое значение для sectionNameKeyPath: при инициализации FRC.

Изменение:

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, то каждый экземпляр будет иметь свой собственный раздел в табличном представлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...