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)
}