Ios 如何为核心数据中的一对多托管对象使用谓词

Ios 如何为核心数据中的一对多托管对象使用谓词,ios,swift,core-data,nspredicate,nsmanagedobject,Ios,Swift,Core Data,Nspredicate,Nsmanagedobject,我目前有两个核心数据的托管对象,它们具有一对多关系 目标 扩展目标{ @nonobjc公共类func createFetchRequest()->NSFetchRequest{ 返回NSFetchRequest(entityName:“目标”) } @NSManaged公共变量标题:String @NSV管理的公共var日期:日期 @NSManaged public var进度:NSSet? } 进步 扩展进度{ @nonobjc公共类func createFetchRequest()->NS

我目前有两个核心数据的托管对象,它们具有一对多关系

目标

扩展目标{
@nonobjc公共类func createFetchRequest()->NSFetchRequest{
返回NSFetchRequest(entityName:“目标”)
}
@NSManaged公共变量标题:String
@NSV管理的公共var日期:日期
@NSManaged public var进度:NSSet?
}
进步

扩展进度{
@nonobjc公共类func createFetchRequest()->NSFetchRequest{
返回NSFetchRequest(entityName:“进度”)
}
@NSV管理的公共var日期:日期
@NSManaged public var注释:字符串?
@NSV管理的公共var目标:目标
}
对于每个目标,您都可以有多个
Progress
对象。问题是,当我以特定的
目标
作为谓词请求获取
进度
时,没有返回任何内容。我怀疑我没有正确使用谓词

我就是这样要求他们的

  • 首先,我为表视图控制器获取
    Goal
  • var fetchedResultsController:NSFetchedResultsController!
    如果fetchedResultsController==nil{
    let request=Goal.createFetchRequest()
    let sort=NSSortDescriptor(键:“日期”,升序:false)
    request.sortDescriptors=[sort]
    request.fetchBatchSize=20
    fetchedResultsController=NSFetchedResultsController(fetchRequest:request,managedObjectContext:self.context,sectionNameKeyPath:“title”,cacheName:nil)
    fetchedResultsController.delegate=self
    }
    fetchedResultsController.fetchRequest.predicate=goalPredicate
    做{
    请尝试fetchedResultsController.performFetch()
    }抓住{
    打印(“获取失败”)
    }
    
  • 并将结果传递到下一个屏幕,
    Detail
    view controller:
  • 如果让vc=storyboard?。实例化eviewcontroller(带标识符:“Detail”)为?详细视图控制器{
    vc.goal=fetchedResultsController.object(位于:indexPath)
    navigationController?.pushViewController(vc,动画:true)
    }
    
  • 最后,我使用
    Goal
    作为
    Detail
    视图控制器的谓词获取
    Progress
  • var目标:目标!
    让progressRequest=Progress.createFetchRequest()
    progressRequest.predicate=NSPredicate(格式:“目标==%@”,目标)
    如果让进步=尝试?self.context.fetch(progressRequest){
    打印(“进度:\(进度)”)
    如果progress.count>0{
    fetchedResult=progress[0]
    打印(“fetchedResult:\(fetchedResult)”)
    }
    }
    
    目标
    被正确返回,但我没有因为
    进度
    而得到任何回报。我试过:

    progressRequest.predicate=NSPredicate(格式:“goal.title==%@”,goal.title)
    

    progressRequest.predicate=NSPredicate(格式:“任意目标==%@”,目标)
    
    但结果还是一样

    以下是我如何建立关系的:

    //用户的进度输入
    让进度=进度(上下文:self.context)
    progress.date=日期()
    progress.comment=commentTextView.text
    //获取相关目标
    var goalForProgress:进球!
    让goalRequest=Goal.createFetchRequest()
    goalRequest.predicate=NSPredicate(格式:“title==%@”,titleLabel.text!)
    如果让目标=尝试?self.context.fetch(goalRequest){
    如果goal.count>0{
    goalForProgress=目标[0]
    }
    }
    //建立目标和进度之间的关系
    goalForProgress.progress.insert(进度)
    //拯救
    如果self.context.hasChanges{
    做{
    尝试self.context.save()
    }抓住{
    打印(“保存时出错:\(error.localizedDescription)”)
    }
    }
    
    实际上,您不需要重新读取数据。你可以从这段关系中得到进展

    • progress
      声明为本机
      Set

      @NSManaged public var progress: Set<Progress>
      
    • 在第一个视图中,控制器过滤进度

      let goal = fetchedResultsController.object(at: indexPath)
      if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController,
         let progress = goal.progress.first(where: {$0.goal.title == goal.title}) {
          vc.progress = progress
          navigationController?.pushViewController(vc, animated: true)
      }
      

    并考虑以复数形式命名多个关系(<代码>进度< /COD>)< /P> < P>我发现这是由于核心数据错误,核心数据懒散地加载数据,除非显式访问数据,否则将不显示值。 您可以执行以下操作之一:

    let goal=fetchedResultsController.object(位于:indexPath)
    如果让vc=storyboard?.InstanceEviewController(标识符为:“详细信息”)作为?详细视图控制器,
    让progress=goal.progress.first(其中:{$0.goal.title==goal.title}){
    vc.goalTitle=goal.title
    vc.date=progress.date
    如果let comment=progress.comment{
    vc.comment=comment
    }
    navigationController?.pushViewController(vc,动画:true)
    }
    
    或者将
    returnsObjectsAsFaults
    设置为
    false


    这是一个很好的主题。

    var目标:目标
    声明变量,但未设置。我正在传递上一屏幕中的值,
    vc.goal=fetchedResultsController.object(at:indexPath)
    ,并将其用作谓词。对不起,我的错,在
    DetailViewController
    中在哪里运行获取代码?而不是
    尝试?
    捕捉错误。无需担心。我在
    viewDidLoad()
    中运行了获取代码。谢谢您的回答。它给了我一个错误,
    Progress
    没有
    title
    ,因此我将其更改为
    $0.goal.title
    ,但现在当我单击表的单元格时,该单元格会高亮显示,但由于某种原因,它不会导航到
    详细信息
    视图控制器。对,我更新了答案。然后检查模型中的关系设置是否正确。我更新了我的问题,以包括如何设置关系。在保存上下文之前,我先获取目标,然后插入(:at:)Progress对象。我指的是核心数据模型中的关系,尤其是inve
    let goal = fetchedResultsController.object(at: indexPath)
    if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController,
       let progress = goal.progress.first(where: {$0.goal.title == goal.title}) {
        vc.progress = progress
        navigationController?.pushViewController(vc, animated: true)
    }