【问题标题】:CoreData ordered relationships - batch unfaulting using NSFetchRequestCoreData 有序关系 - 使用 NSFetchRequest 进行批处理无故障
【发布时间】:2013-06-14 09:20:24
【问题描述】:

背景 - 批次无误:
NSFetchRequest 允许批量无故障 - 例如,使用 1000 个结果的查询,它会将所有结果都作为故障,然后它会一次无故障 X 对象(即索引 0-20,然后 21-40 等)

这种行为在 NSFetchResultsController 中用于 UITableViewDataSource 时非常有用,并且它允许快速 UI 滚动,因为它不会一个接一个地排除对象。

现在是我的问题:
我正在为对象列表使用有序关系,比如说 Posts

由于 Post 可能出现在我的模型上的许多列表中,我无法将其索引存储在 Post 实体的每个列表中并将其用作参数用于订购结果。

目前,我还没有找到 NSFetchRequest 按照这个顺序获取的方法,所以我不能使用它的批处理无故障。所以我正在处理与索引的关系,并且我最终会一个接一个地无误,这会导致滚动不顺畅。

NSFetchResultsController 有没有办法根据订单关系进行抓取? 或者,是否存在非私有的批处理无故障 API?

【问题讨论】:

    标签: ios core-data nsfetchrequest fault nsfetchedresultscontroller


    【解决方案1】:

    目前我有一个解决方案,但不是一个干净的解决方案:
    我想以有序的关系按 20 组无故障地批处理。

    所以,每次我处理一个索引除以 20(索引 % 20 == 0)的索引时, 我为接下来的 20 个使用新的 NSFetchRequest,并通过调用一个通用字段名称来消除它们的错误。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        if (indexPath.row % 20 == 0) {
            NSArray *objectsToUnfault = [[someObject.orderedRelationship array] subarrayWithRange:NSMakeRange(indexPath.row, MIN(20, [someObject.orderedRelationship count] - indexPath.row))];
            // It's important to hold on this array, otherwise objects fault back
            self.lastPrefetch = [self preFetchEntityOfClass:[Post class] faultObjects:objectsToUnfault error:&error];
        }
    //... continue and create cell
    }
    
    
    - (NSArray *)preFetchEntityOfClass:(Class)entityClass faultObjects:(NSArray*)objects error:(NSError **)error {
        NSEntityDescription *entityDescription = [NSEntityDescription entityForName:NSStringFromClass(entityClass) inManagedObjectContext:self.managedObjectContext];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF in %@", objects];
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        [request setEntity:entityDescription];
        [request setPredicate:predicate];
        [request setFetchBatchSize:MIN([objects count], 20)];
        NSArray *results = [self.managedObjectContext executeFetchRequest:request error:error];
        // I assume all my objects has this field "uid"
        NSArray *resultsUid = [results valueForKey:@"uid"]; //Batch unfaulting (results is a BatchFaultArray, private class type)
        if ([resultsUid count] != [results count]) {
            NSLog(@"Error: wrong count of uids"); //We need to use resultsUid, to avoid compiler opt
        }
        return results;
    }
    

    【讨论】:

      【解决方案2】:

      希望我能正确理解你的问题,

      找到答案了,请看adonoho的答案和cmets

      NSFetchedResultsController and NSOrderedSet relationships

      【讨论】:

      • 对不起,但正如我所说,就我而言,该帖子可能出现在未知(大量)列表中,因此我无法在每个列表中保留其索引。
      猜你喜欢
      • 2012-02-11
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 2012-08-07
      • 2016-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多