获取时核心数据中的重复记录

时间:2009-09-20 23:58:27

标签: iphone objective-c cocoa cocoa-touch core-data

民间,

我的iPhone项目中有一些涉及Core Data的益智游戏。在两个单独的视图控制器实例中的viewDidLoad方法期间,我调用以下方法:

- (NSFetchedResultsController *)getStudentResults:(NSString *)classRoom forWeekStarting:(NSDate *)startDate andEnding:(NSDate *)endDate {
    AttendanceAppDelegate *appDelegate = (AttendanceAppDelegate *)[[UIApplication sharedApplication] delegate];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:[appDelegate managedObjectContext]];

    int secondsInAWeek = 60 * 60 * 24 * 7;
    NSDate *today = [[NSDate alloc] init];
    NSDate *nextWeek = [[NSDate alloc] initWithTimeIntervalSinceNow:secondsInAWeek];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(student.classRoom like %@) AND (dateTime >= %@) AND (dateTime <= %@)", classRoom, startDate, endDate];
    [request setPredicate:predicate];
    [request setEntity:entityDescription];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dateTime" ascending:YES];
    NSArray *descriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [request setSortDescriptors:descriptors];
    [descriptors release];
    [sortDescriptor release];
    [nextWeek release];
    [today release];


    NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[appDelegate managedObjectContext] sectionNameKeyPath:nil cacheName:@""];
    NSError *error; 
    if (![fetchedResultsController performFetch:&error])
        NSLog(@"Error performing fetch on fetchedResultsController: %@", [error localizedDescription]);

    if (fetchedResultsController == nil || [[fetchedResultsController fetchedObjects] count] == 0) { 
        Student *student = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:[appDelegate managedObjectContext]];
        NSData *classRoomStudentData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"STUDENT_ATTENDANCE" ofType:@"XML"]];
        [student setClassRoom:@"default"];
        [student buildWithStudentData:classRoomStudentData startingWithXPathNode:@"//attendance"];

        NSError *error; 
        if (![[appDelegate managedObjectContext] save:&error]) { 
            NSLog(@"Error saving the managedObjectContext: %@", [error localizedDescription]);
        }

        if (![fetchedResultsController performFetch:&error])
            NSLog(@"Error performing fetch on fetchedResultsController: %@", [error localizedDescription]);
    }
    return fetchedResultsController;
}

每次运行我的应用程序时,学生对象的数量会增加原始实体的数量(每个原始实体重复一次)。因此,如果我从4开始,下次我得到8,然后是12,然后是16,等等。我似乎无法弄清楚为什么因为解析XML的代码仅在fetch没有返回对象时被调用。

任何帮助都将不胜感激,谢谢。

- 迈克尔

1 个答案:

答案 0 :(得分:4)

您不仅在获取没有返回对象时插入新对象:查看代码

if (fetchedResultsController == nil || [[fetchedResultsController fetchedObjects] count] == 0)

如果无法正确初始化NSfetchedResultsController,也会插入它们。因此,如果您每次添加新对象时都反复无法正确初始化它。

建议是初始化NSfetchedResultsController,如Apple提供的所有示例代码所示。基本上,您首先验证fetchedResultsController是否为nil。如果没有,您只需返回变量。否则,您将其初始化。

请参阅我对此问题的回答以获取示例:

How to properly configure NSFetchedResultsController