从 Swift Core Data 中的一对多关系中获取对象
Getting objects from to-many relationship in Swift Core Data
我在核心数据中与Swift一起使用多对多关系时遇到了一些困难。
我的数据模型
我想做的是使用 Country
的实例,然后显示属于该国家/地区的所有 Contacts
公民。因为我一直在尝试这样做,所以我构建了一个 UITableViewController 来显示该国的所有公民。然而,我在从关系 citizensOfCountry
中获取实际 Contacts
方面遇到了重大问题。这是我正在使用的代码(仅相关部分)。
class ShowingCitizensOfCountry: UITableViewController {
var countryToShow: Country?
//This is a value that is passed by a prepareForSegue method
override func viewDidLoad() {
//how do I get a list/set/other iterable object of Contacts?
//***Line in question***
let listOfPeople = countryToShow!.citizensOfCountry
for citizen in listOfPeople {
println(citizen)//THIS IS NOT WORKING
}
}
所以,这根本不起作用。现在在 for 循环中我得到一个编译器错误 Type 'Contacts' does not conform to protocol 'Sequence Type'
。我不明白的是,它只是联系人类型...我认为这将是某种集合。所以,那没有用,所以我尝试了这个。
let listOfPeople = countryToShow!.citizensOfCountry as! [Contacts]
这也不起作用,我收到错误 'NSArray' is not a subtype of 'Contacts'
。接下来我尝试使用 NSSet 进行转换。
let listOfPeople = countryToShow!.citizensOfCountry as! NSSet<Contacts>
不幸的是,这也不起作用,我收到警告 Cast from 'Contacts' to unrelated type 'NSSet' always fails
和 Cannot specialize non-generic type 'NSSet'
。接下来我尝试了别的东西。我尝试使用 valueForKey
方法。
let listOfPeople = countryToShow!.citizensOfCountry.valueForKey("name") as! Set<String>
这行得通!我可以打印出该国所有公民的名字。但是我不明白为什么。为什么当我使用 valueForKey("name")
时它有效但我无法获得个人联系人?有没有更好的方法来做到这一点,我只是错过了?非常感谢任何关于为什么我无法从单个 Country
中获得 Contacts
集合的解释。谢谢。
您的错误的原因是一对多关系导致 NSSet
。您对这些集合进行迭代的所有尝试都应考虑到这一点。
更好的方法是实现 NSFetchResultsController
,这是在 table 视图中显示核心数据的标准方式。
- 在 FRC 中,找人
- 根据需要对 FRC 进行排序
- 给它一个过滤
countryToShow
的谓词
FRC 实现:
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest(entityName: "Contact")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
fetchRequest.predicate = NSPredicate(format:"countryOfOrigin = %@", self.countryToShow!)
let aFetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!,
sectionNameKeyPath: nil, cacheName: nil)
_fetchedResultsController = aFetchedResultsController
var error: NSError? = nil
if !_fetchedResultsController!.performFetch(&error) {
NSLog("%@", error!)
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
我把Contacts改成了更合适的单数。
抱歉,因为我真的很累,所以无法阅读所有内容。但是从我读过的内容来看,您想获得一个应该是 NSSet 的国家/地区的公民。要做到这一点,您只需执行以下操作:
let contacts = yourArrayOfCountries.flatMap {
[=10=].citizensOfCountry.allObjects as! [Contacts]
}
根据您的评论:
let contacts = countryToShow!.citizensOfCountry.allObjects as! [Contacts]
我在核心数据中与Swift一起使用多对多关系时遇到了一些困难。
我的数据模型
我想做的是使用 Country
的实例,然后显示属于该国家/地区的所有 Contacts
公民。因为我一直在尝试这样做,所以我构建了一个 UITableViewController 来显示该国的所有公民。然而,我在从关系 citizensOfCountry
中获取实际 Contacts
方面遇到了重大问题。这是我正在使用的代码(仅相关部分)。
class ShowingCitizensOfCountry: UITableViewController {
var countryToShow: Country?
//This is a value that is passed by a prepareForSegue method
override func viewDidLoad() {
//how do I get a list/set/other iterable object of Contacts?
//***Line in question***
let listOfPeople = countryToShow!.citizensOfCountry
for citizen in listOfPeople {
println(citizen)//THIS IS NOT WORKING
}
}
所以,这根本不起作用。现在在 for 循环中我得到一个编译器错误 Type 'Contacts' does not conform to protocol 'Sequence Type'
。我不明白的是,它只是联系人类型...我认为这将是某种集合。所以,那没有用,所以我尝试了这个。
let listOfPeople = countryToShow!.citizensOfCountry as! [Contacts]
这也不起作用,我收到错误 'NSArray' is not a subtype of 'Contacts'
。接下来我尝试使用 NSSet 进行转换。
let listOfPeople = countryToShow!.citizensOfCountry as! NSSet<Contacts>
不幸的是,这也不起作用,我收到警告 Cast from 'Contacts' to unrelated type 'NSSet' always fails
和 Cannot specialize non-generic type 'NSSet'
。接下来我尝试了别的东西。我尝试使用 valueForKey
方法。
let listOfPeople = countryToShow!.citizensOfCountry.valueForKey("name") as! Set<String>
这行得通!我可以打印出该国所有公民的名字。但是我不明白为什么。为什么当我使用 valueForKey("name")
时它有效但我无法获得个人联系人?有没有更好的方法来做到这一点,我只是错过了?非常感谢任何关于为什么我无法从单个 Country
中获得 Contacts
集合的解释。谢谢。
您的错误的原因是一对多关系导致 NSSet
。您对这些集合进行迭代的所有尝试都应考虑到这一点。
更好的方法是实现 NSFetchResultsController
,这是在 table 视图中显示核心数据的标准方式。
- 在 FRC 中,找人
- 根据需要对 FRC 进行排序
- 给它一个过滤
countryToShow
的谓词
FRC 实现:
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest(entityName: "Contact")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
fetchRequest.predicate = NSPredicate(format:"countryOfOrigin = %@", self.countryToShow!)
let aFetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!,
sectionNameKeyPath: nil, cacheName: nil)
_fetchedResultsController = aFetchedResultsController
var error: NSError? = nil
if !_fetchedResultsController!.performFetch(&error) {
NSLog("%@", error!)
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
我把Contacts改成了更合适的单数。
抱歉,因为我真的很累,所以无法阅读所有内容。但是从我读过的内容来看,您想获得一个应该是 NSSet 的国家/地区的公民。要做到这一点,您只需执行以下操作:
let contacts = yourArrayOfCountries.flatMap {
[=10=].citizensOfCountry.allObjects as! [Contacts]
}
根据您的评论:
let contacts = countryToShow!.citizensOfCountry.allObjects as! [Contacts]