coredata sqlite格式错误的DB

时间:2010-09-02 16:33:15

标签: iphone cocoa sqlite core-data

我的coredata sqlite DB存在问题,它存放了一本书数据库。崩溃后,用户体验出现了问题,即他/她的桌面视图中的数据无法正常显示。

这是因为performFetch方法返回错误:

[NSFetchedResultsController deleteCacheWithName:nil];
if (![[self fetchedResultsController] performFetch:&error]) { 
        //NSArray *array = [[self fetchedResultsController] fetchedObjects];
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
#ifdef DEBUG
        abort();
#endif
    }

导致此错误消息:

未解决的错误错误域= NSCocoaErrorDomain代码= 134060“操作无法完成。(Cocoa错误134060.)”UserInfo = 0x1dff80 {reason =索引312处的获取对象具有无序部分名称'Z.对象必须按部分名称'},{进行排序     reason =“索引312处的获取对象具有乱序部分名称'Z.对象必须按部分名称排序'”;

当我使用'SQLite Database Browser 2.0 b1'查看sqlite文件时,每个实体的属性似乎都没问题。

当我删除一些被提及的实体时,一切正常。

我想知道如何找出上述实体的确切错误并修复它,以便用户可以再次使用他/她的数据。当然,我想修复导致格式错误的数据库的错误,但这篇帖子没有引起关注。

是否有任何提示我可以查看或在我的数据库中可能有什么格式错误或“无序部分名称”是什么?

这是我的fetchedResultsController的代码:

- (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }


    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity;
    entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:[[GlobalData sharedInstance] managedObjectContext]];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:10];

    //set searchPredicate
    NSPredicate *predicate = nil;
    if (self.bibList != nil) {
        predicate = [NSPredicate predicateWithFormat:@"ANY BibLists.name LIKE %@", self.bibList.name];      
    }

    if (predicate) {
        [fetchRequest setPredicate:predicate];
    }


    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor;   
    NSString *sortDescriptorString = nil;       
    sortDescriptorString = @"title";
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortDescriptorString ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];   
    [fetchRequest setSortDescriptors:sortDescriptors];

    NSString *sectionNameKeyPath = nil;
    sectionNameKeyPath = @"uppercaseFirstLetterOfTitle";

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController;
    aFetchedResultsController = [[NSFetchedResultsController alloc] 
                             initWithFetchRequest:fetchRequest 
                             managedObjectContext:[[GlobalData sharedInstance] managedObjectContext] 
                             sectionNameKeyPath:sectionNameKeyPath 
                             cacheName:@"Bibliography"];

    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    return fetchedResultsController;
}    

由于 b00tsy

2 个答案:

答案 0 :(得分:1)

documentation中的以下语句提示错误。

  

如果此密钥路径与fetchRequest中第一个排序描述符指定的密钥路径不同,则它们必须生成相同的相对排序。

当单独对标题进行排序时,似乎索引312处的项目不在正确的部分中。这可能是title属性以非字母或小写字母开头的结果,使用词法排序将其放在Z部分之后,但是item的uppercaseFirstLetterOfTitle的值不是'Z'。作为建议,尝试在uppercaseFirstLetterOfTitle上添加排序描述符作为第一个排序描述符,然后在title上添加排序描述符。

答案 1 :(得分:1)

我认为这里发生的事情是你的SQL存储已损坏和/或你有一个不寻常的sectionNameKeyPath

Core Data架构使用Z作为所有SQL列名称的前缀,因此名称'Z的错误表明SQL表已损坏。要测试它,请直接执行获取请求,而不是使用获取的结果控制器,看看是否可以获取所有对象。

如果不能,则SQL存储已损坏。最有可能的是,某些表组件只是名称'Z而不是ZAttributeName。您必须直接编辑SQL,但由于自定义私有模式,这很棘手。请参阅this post以了解要查找的内容。没有任何工具可以做到这一点,因为商店的腐败是如此罕见。

如果获取有效,则问题在于sectionNameKeyPath被传递给获取的结果控制器。现在,看起来你有一个带有title属性第一个字母的实体属性。 (这是多余的,因为默认情况下,FRC将根据任何字符串属性自动返回字母部分。)尝试将sectionNameKeyPath更改为标题属性名称(最可能是“标题”)。无论如何,只需完全省略uppercaseFirstLetterOfTitle属性即可。