Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 未调用NSFetchedResultsController自定义排序_Iphone_Objective C_Cocoa Touch_Core Data_Nsfetchedresultscontroller - Fatal编程技术网

Iphone 未调用NSFetchedResultsController自定义排序

Iphone 未调用NSFetchedResultsController自定义排序,iphone,objective-c,cocoa-touch,core-data,nsfetchedresultscontroller,Iphone,Objective C,Cocoa Touch,Core Data,Nsfetchedresultscontroller,我目前正在尝试使用NSFetchedResultsController从核心数据填充项目中的UITableView。我正在使用带有比较器的自定义搜索(尽管我也尝试了选择器,但遇到了相同的问题): 当我进入这个选项卡时,我已经记录了整个程序,发现NSFetchedResultsController在获取时甚至没有进入比较器块。而是使用一些默认的排序方法对其进行排序 但是,如果我删除并添加一个具有objectName的对象,它就会进入comparator块并正确地对表进行排序 为什么NSFetche

我目前正在尝试使用NSFetchedResultsController从核心数据填充项目中的UITableView。我正在使用带有比较器的自定义搜索(尽管我也尝试了选择器,但遇到了相同的问题):

当我进入这个选项卡时,我已经记录了整个程序,发现NSFetchedResultsController在获取时甚至没有进入比较器块。而是使用一些默认的排序方法对其进行排序

但是,如果我删除并添加一个具有objectName的对象,它就会进入comparator块并正确地对表进行排序

为什么NSFetchedResultsController在更改托管对象模型之前不使用比较器进行排序


注意:我也尝试过关闭缓存和/或在viewDidLoad:中执行提取,但似乎提取多少次并不重要,而是何时。出于某种原因,它只在对象模型更改后使用我的排序。

对不起,您是否错过了代码片段的最后一个获取部分

NSError *error;
BOOL success = [aFetchedResultsController performFetch:&error];
也不要忘记发布请求:

[fetchRequest release];

有几件事我能想到。首先,尽管这可能不是您的问题,但您不能对瞬态属性进行排序。但更可能的情况是,在SQL存储支持的模型中进行排序时,比较器会“编译”为SQL查询,并且并非所有Objective-C函数都可用。在这种情况下,您需要在执行提取后在内存中进行排序


编辑:请参见此部分,特别是“获取谓词和排序描述符”部分。

我看到了相同的问题,解决此问题的方法是修改对象,保存更改,然后将其恢复为原始值,然后再次保存

    // try to force an update for correct initial sorting bug
NSInteger count = [self.fetchedResultsController.sections count];
if (count > 0) {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
    count = [sectionInfo numberOfObjects];
    if (count > 0) {
        NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
        NSString *name = [obj valueForKey:@"name"];
        [obj setValue:@"X" forKey:@"name"];
        // Save the context.
        [self saveContext];
        [obj setValue:name forKey:@"name"];
        // Save the context.
        [self saveContext];
    }
}
//尝试强制更新正确的初始排序错误
NSInteger计数=[self.fetchedResultsController.sections计数];
如果(计数>0){
id sectionInfo=[[self.fetchedResultsController sections]objectAtIndex:0];
计数=[sectionInfo numberOfObjects];
如果(计数>0){
NSManagedObject*obj=[self.fetchedResultsController对象索引路径:[NSIndexPath indexPathForRow:0第0节:0]];
NSString*name=[obj valueForKey:@“name”];
[obj setValue:@“X”forKey:@“name”];
//保存上下文。
[自我保护背景];
[obj setValue:name forKey:@“name”];
//保存上下文。
[自我保护背景];
}
}

不,我只是没有把它包含在代码片段中。我已经包括了整个方法,如果这让它更清楚的话。它们不是瞬态属性,但是你的其他建议似乎肯定是问题所在。唯一的问题是,我依赖fetchedresultscontroller向表视图提供节名称等,因此每次在内存中排序都很困难(我认为)。你建议怎么做?我的另一个问题是,为什么比较器在对象模型改变后会阻塞?非常感谢。实际上,这里更普遍的问题是,我将节与节索引一起实现到我的表视图中。我把任何以数字开头的对象放在一个“123”部分(这是可行的),但我希望这个部分像iPod应用程序一样位于底部。根据苹果的应用程序,数字应该是sectionIndex中的最后一个选项(我正在使用UILocalizedIndexedCollation生成节索引)。然而,似乎没有办法取回这些章节,让数字排在最后。你知道有比自定义排序更可靠的方法吗?我只是猜测一下,但我认为在对象模型更改后,比较器块会工作,因为图形已经在内存中。但这只是一个猜测。我相信,手动排序的方法是将NSArrayController子类化,这样就失去了NSFetchedResultsController的优势。但是,正如你所说,根本问题是你想把数字排到底。在我的脑海中,我会说在你的对象上创建一个排序顺序属性并使用它,但是我还没有用排序描述符做足够的自定义排序。再次感谢Don,看起来你在文档中找到了这个发现。我还通过将所有内容加载到一个数组中,并根据我发现的另一个stackoverflow问题,使用该数组填充列表并确定部分来实现这一点。一切都很好,很好!很高兴你让它工作了。我在《Cocoa是我的女朋友》上也发现了这一点,这也建议使用sortOrder属性:
    // try to force an update for correct initial sorting bug
NSInteger count = [self.fetchedResultsController.sections count];
if (count > 0) {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
    count = [sectionInfo numberOfObjects];
    if (count > 0) {
        NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
        NSString *name = [obj valueForKey:@"name"];
        [obj setValue:@"X" forKey:@"name"];
        // Save the context.
        [self saveContext];
        [obj setValue:name forKey:@"name"];
        // Save the context.
        [self saveContext];
    }
}