Iphone coredata sqlite格式错误的数据库

Iphone coredata sqlite格式错误的数据库,iphone,cocoa,sqlite,core-data,Iphone,Cocoa,Sqlite,Core Data,我的coredatasqlite数据库有问题,它托管一个book数据库。崩溃后,用户体验到的问题是,数据不再正确地显示在他/她的tableview中 这是因为performFetch方法返回错误: [NSFetchedResultsController deleteCacheWithName:nil]; if (![[self fetchedResultsController] performFetch:&error]) { //NSArray *array = [[s

我的coredatasqlite数据库有问题,它托管一个book数据库。崩溃后,用户体验到的问题是,数据不再正确地显示在他/她的tableview中

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

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

未解决的错误Domain=NSCocoaErrorDomain Code=134060“该操作无法完成。(Cocoa错误134060)。”UserInfo=0x1df80{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

下面的语句提示了错误

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


仅对标题进行排序时,索引312处的项目似乎不在正确的部分。这可能是由于标题属性以非字母或小写字母开头,使用词汇排序会将其放在Z部分之后,但项目的大写FirstLetterofTitle的值不是“Z”。建议尝试添加
大写字母firstletoftitle上的排序描述符
作为第一个排序描述符,然后在
标题
上添加排序描述符

我认为这里发生的情况是SQL存储已损坏和/或出现异常的
sectionNameKeyPath

核心数据架构将所有SQL列名的前缀设置为
Z
,因此名称为
'Z
的错误表明SQL表已损坏。若要进行测试,请直接执行fetch请求,而不是使用fetch results控制器,并查看是否可以提取所有对象

如果不能,则SQL存储已损坏。很可能,某些表组件只是名称
'Z
,而不是类似
ZAttributeName
的内容。您必须直接编辑SQL,但由于自定义私有架构,这很棘手。请参阅了解要查找的内容。由于这家商店的腐败是如此罕见


如果提取工作正常,那么问题在于将
sectionNameKeyPath
交给提取结果控制器。现在,您似乎有一个带有title属性第一个字母的entity属性。(这是多余的,因为默认情况下,FRC将根据任何字符串属性自动返回字母部分。)尝试将
sectionNameKeyPath
更改为仅标题属性名称(很可能是“title”)。在任何情况下,只需完全省去
uppercaseFirstLetterOfTitle
属性。

包括您的获取请求代码和添加的任何排序描述符。
uppercaseFirstLetterOfTitle
是临时属性还是持久属性?是否存在以小写字母开头的条目terOfTitle是一个临时属性。在
title
中有一些实体具有小写字母和非ascii字母。请尝试以下答案:在处理大型数据集时,正如苹果在WWDC会话118视频中所建议的那样,大写FirstLetteroftitle属性非常有用。这可能会增加复杂性,从而提高性能尽管如此(这篇文章是明确的证据)这就是为什么我一直看到这个。我认为很多人都在不必要地使用它。这不是新手的技术。谢谢你的回答。managedObjectContext上的直接fetchRequest起了作用。问题是有小写标题和非ascii标题可用,这导致了FalconScreek提到的问题。分发使用
uppercaseFirstLetterOfTitle
是没有选项的,因为我不想为每个标题都设置一个部分。我只想为每个
uppercaseFirstLetterOfTitle
设置一个部分。您能否包括使用FRC中的默认部分显示的代码,该默认部分会像Contacts应用程序一样显示tableview部分和索引?谢谢您的回复。谢谢s将小写字母作为标题正是问题所在。但由于
uppercasefirstletoftitle
是一个临时属性,我没有设法将其用作排序描述符。我应该将其持久化还是有其他选项来处理该情况?还是应该检查标题生成是否以大写字母开头?根据TechZen,您可以删除
大写字母firstletteroftitle
。将
@title
传递到
sectionNameKeyPath:
的默认行为将提供所需的行为。它不等同于“按标题分组”在SQLwell中,每个标题都有一个部分,我只希望每个第一个字母都有一个部分。还是我缺少了s.th.out?在实现
UITableViewDataSourceDelegate
协议方法时,需要使用
NSFetchedResultsSectionInfo
协议方法。您的意思是我应该手动生成对章节/章节索引等进行排序?目前,我强制所有标题都使用大写首字母。这是可行的,但我想阻止使用这种方法,因为我也对LastN进行排序