You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NSFetchedResultsController循环时标题未更新问题求助

解决NSFetchedResultsController嵌套遍历标题不变的问题

听起来你遇到的情况是:嵌套使用NSFetchedResultsController遍历数据时,strats.sexfluence_user_stratagy_title始终显示同一个值,但其他内容都能正常展示。我来帮你梳理几个最可能的原因和对应的解决办法:

一、检查NSFetchedResultsController的复用逻辑

你在循环里每次调用fetchedResultsControllerStrat:方法并赋值给self.fetchedResultsControllerStrats,如果这个属性的getter方法或者fetchedResultsControllerStrat:内部有缓存旧实例的逻辑(比如判断如果已经存在FRC就直接返回),那每次循环拿到的都是第一次创建的FRC,对应的fetchedObjects自然也是同一批数据,标题就会重复。

解决办法:确保fetchedResultsControllerStrat:每次调用都创建新的NSFetchedResultsController实例,并且不使用缓存。示例代码如下:

- (NSFetchedResultsController *)fetchedResultsControllerStrat:(NSNumber *)objectiveId {
    // 每次都创建新的请求和FRC,不复用旧实例
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Stratagy"];
    
    // 务必设置正确的排序器(FRC要求必须有排序)
    fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"sexfluence_user_stratagy_title" ascending:YES]];
    
    // 用传入的objectiveId设置谓词,确保过滤对应的数据
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sexfluence_user_objectives_id == %@", objectiveId];
    fetchRequest.predicate = predicate;
    
    NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                        managedObjectContext:self.managedObjectContext
                                                                          sectionNameKeyPath:nil
                                                                                   cacheName:nil]; // 不要设置cacheName,避免缓存
    
    // 执行获取数据操作
    NSError *fetchError = nil;
    if (![frc performFetch:&fetchError]) {
        NSLog(@"获取Stratagy数据失败: %@", fetchError.localizedDescription);
    }
    
    return frc;
}

二、验证谓词的正确性

如果fetchedResultsControllerStrat:里的谓词设置错误,比如用了固定值、变量名写错(比如把sexfluence_user_objectives_id写成了其他字段),就会导致每次都获取同一批Stratagy数据,标题自然不变。

你可以在循环里打印关键信息,排查数据是否匹配:

for (Objective * objs in self.fetchedResultsControllerObj.fetchedObjects) { 
    NSLog(@"当前Objective ID: %@", objs.sexfluence_user_objectives_id);
    self.fetchedResultsControllerStrats = [self fetchedResultsControllerStrat:objs.sexfluence_user_objectives_id]; 
    NSLog(@"对应Stratagy数量: %lu", (unsigned long)self.fetchedResultsControllerStrats.fetchedObjects.count);
    for (Stratagy * strats in self.fetchedResultsControllerStrats.fetchedObjects) { 
        NSLog(@"Stratagy标题: %@", strats.sexfluence_user_stratagy_title);
        RADataObject *stratagies = [RADataObject dataObjectWithName:strats.sexfluence_user_stratagy_title...
    }
}

如果发现不同Objective ID对应的Stratagy数量或标题完全一致,那肯定是谓词设置出了问题。

三、排查RADataObject的创建逻辑

另外,你用到的RADataObject dataObjectWithName:工厂方法如果内部有复用实例的逻辑(比如缓存了创建过的对象),也可能导致后续的标题被覆盖或者没有更新。

可以临时改成直接初始化RADataObject的方式测试:

RADataObject *stratagies = [[RADataObject alloc] init];
stratagies.name = strats.sexfluence_user_stratagy_title;
// 其他属性赋值

如果这样标题正常了,那问题就出在这个工厂方法的缓存逻辑上,需要调整它的实现。

更优的替代方案:使用Core Data关系

其实如果Objective和Stratagy在Core Data模型里已经设置了一对多的关系(比如Objective有一个stratagies属性对应关联的所有Stratagy),完全可以不用嵌套FRC,直接通过关系获取数据,这样代码更简洁也更不容易出错:

for (Objective *objs in self.fetchedResultsControllerObj.fetchedObjects) { 
    // 直接遍历Objective关联的Stratagy集合
    for (Stratagy *strats in objs.stratagies) { 
        RADataObject *stratagies = [RADataObject dataObjectWithName:strats.sexfluence_user_stratagy_title...
        // 后续逻辑
    }
}

内容的提问来源于stack exchange,提问作者Duny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:34:33