NSFetchedResultsController和多对多关系无法正常工作

问题描述:

好的,我在过去的1-2周中一直在寻找并尝试这种情况,但我没有得到它的工作。我可以在没有NSFRC的情况下达到我想要的水平,但是出于性能原因和快速考虑,我希望能够与NSFRC一起完成。 所以,我有2个实体的DataModel - 看到图片 to-many RelationshipNSFetchedResultsController和多对多关系无法正常工作

有一个帐户,一个帐户可以有多个accountchanges - 这是相当明显的。 所以我希望能够选择一个帐户,然后显示该特定帐户的所有AccountChanges。 到目前为止,我能够获得帐户,并访问cellForRow函数中的NSSet,但我没有得到正确的部分和numberOfRowsInSection - 这是主要问题。

下面是一些代码:

func numberOfSections(in tableView: UITableView) -> Int { 

    print("Sections : \(self.fetchedResultsController.sections?.count)") 
    if (self.fetchedResultsController.sections?.count)! <= 0 { 
     print("There are no objects in the core data - do something else !!!") 
    } 
    return self.fetchedResultsController.sections?.count ?? 0 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    print("Section Name") 
    print(self.fetchedResultsController.sections![section].name) 
    let sectionInfo = self.fetchedResultsController.sections![section] 
    print("Section: \(sectionInfo) - Sections Objects: \(sectionInfo.numberOfObjects)") 
    return sectionInfo.numberOfObjects 
} 

有一些打印报表时仅供参考!

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let myCell = myTable.dequeueReusableCell(withIdentifier: "myCell")! as UITableViewCell 
    let accountBalanceChanges = self.fetchedResultsController.object(at: indexPath) 
    print("AccountBalanceChanges from cell....") 
    print(accountBalanceChanges) 

    let details = accountBalanceChanges.accountchanges! as NSSet 
    print("Print out the details:") 
    print(details) 
    let detailSet = details.allObjects 
    let detailSetItem = detailSet.count // Just for information! 


    let myPrint = detailSet[indexPath.row] as! AccountChanges 
    let myVal = myPrint.category 

    myCell.textLabel?.text = myVal 

    return myCell 
} 

所以,我能够获得数据,但始终只有一个项目,而不是整个集 - 我想由于该段/ numberOfRows是错误的。

这里是我的NSFRC

var fetchedResultsController: NSFetchedResultsController<Accounts> { 
    if _fetchedResultsController != nil { 
     return _fetchedResultsController! 
    } 
    let fetchRequest: NSFetchRequest<Accounts> = Accounts.fetchRequest() 
    // Set the batch size to a suitable number. 
    fetchRequest.fetchBatchSize = 20 
    // Edit the sort key as appropriate. 

    let sortDescriptor = NSSortDescriptor(key: "aName", ascending: false) 
    fetchRequest.sortDescriptors = [sortDescriptor] 


    let predicate = NSPredicate(format: "(ANY accountchanges.accounts = %@)", newAccount!) 
    fetchRequest.predicate = predicate 
    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 

    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.coreDataStack.context, sectionNameKeyPath: nil, cacheName: nil) 
    aFetchedResultsController.delegate = self 
    _fetchedResultsController = aFetchedResultsController 

    do { 
     try _fetchedResultsController!.performFetch() 
    } catch { 
     // Replace this implementation with code to handle the error appropriately. 
     // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     let nserror = error as NSError 
     fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 
    } 

    return _fetchedResultsController! 
} 

我假设它是SortDescriptor或谓语 - 或者两者兼而有之?

任何帮助或至少指示,非常感谢。 我已经尝试了很多不同的方法,但都没有给我正确的结果。

+0

还有一个评论,我试过很多不同的路径在SortDescriptor和谓语/或NSFRC的sectionNameKeyPath - 最失败的消息是:“对许多关键在这里不允许”或“(类别,标题...)的keypath不存在”从上面的代码,谓词似乎工作,但SortDescriptor给我最多的问题......我猜 –

我会做相反的,我的意思是使用FRC来获取所有与某个ID帐户的变化,并使用以下断言:

let predicate = NSPredicate(format: "accounts.aId = %@", ACCOUNTID) 

let predicate = NSPredicate(format: "accounts = %@", account.objectID) 

我会重新将Accounts实体重命名为Account,因为这是一对一的关系,所以将关系重命名为Account。 这就是假设你有一个包含所有帐户的表格视图,并且当你点击一个表格时,它会让你回到它的更改。

var fetchedResultsController: NSFetchedResultsController<AccountChanges> { 
    if _fetchedResultsController != nil { 
     return _fetchedResultsController! 
    } 
    let fetchRequest: NSFetchRequest<AccountChanges> = AccountChanges.fetchRequest() 
    // Set the batch size to a suitable number. 
    fetchRequest.fetchBatchSize = 20 
    // Edit the sort key as appropriate. 

    let sortDescriptor = NSSortDescriptor(key: "aName", ascending: false) 
    fetchRequest.sortDescriptors = [sortDescriptor] 


    let predicate = NSPredicate(format: "accounts.aId = %@", ACCOUNTID) 
    fetchRequest.predicate = predicate 
    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 

    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.coreDataStack.context, sectionNameKeyPath: nil, cacheName: nil) 
    aFetchedResultsController.delegate = self 
    _fetchedResultsController = aFetchedResultsController 

    do { 
     try _fetchedResultsController!.performFetch() 
    } catch { 
     // Replace this implementation with code to handle the error appropriately. 
     // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     let nserror = error as NSError 
     fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 
    } 

    return _fetchedResultsController! 
} 

干杯

+0

我也想过,但我真的不知道不需要任何关系,因为我可以将帐户ID传递给每个帐户更改。但既然我们可以选择使用关系,我想这样做。无论如何,如果没有其他解决方案,我可能会这样做,并重构。我已经在我的数据库中拥有一个唯一的ID,我可以这样做,但是再次,它可以很好地与关系和NSFRC一起工作。 感谢您的建议... –

+0

我的建议仍然涉及关系和NSFRC。你只需要反过来。除了获取帐户并尝试访问帐户中的更改外,还可以使用您传递给谓词的帐户获取帐户的所有更改。 – ubiAle

+0

这不起作用,它只是帐户更改帐户的一对一 - 无法更改,因为一个帐户更改只能影响一个帐户。从账户到账户变化只有一对多 - 见图。正如我上面写的,谓词不是问题,它是SortDescriptor或NSFRC中的keyPath。我得到了正确的帐户,但更改的次数在章节/ numberOfRows中是错误的......如前所述,我可以在没有NSFRC的情况下执行所有操作 - 所以问题不在于获取本身,而是使用NSFRC因为你从rel中获得一个NSSet。 –