访问核心数据中的子对象时出现关系错误
Posted
技术标签:
【中文标题】访问核心数据中的子对象时出现关系错误【英文标题】:Getting relationship fault while accessing a child object in core data 【发布时间】:2017-07-25 09:43:46 【问题描述】:我有两个核心数据实体Contact
和Group
。组有两个属性 existingUsers
和 nonExistingUsers
类型为 Contact
和 toMany 关系
我正在尝试使用groupId
作为谓词来获取组属性。这就是我获取组详细信息的方式
let requestForGroups = NSFetchRequest<NSFetchRequestResult>(entityName: "Group")
requestForGroups.returnsObjectsAsFaults = false
requestForGroups.predicate = NSPredicate(format: "groupId == %@", (groupObject?.groupId)!)
requestForGroups.relationshipKeyPathsForPrefetching = ["existingUsers", "nonExistingUsers"]
do
let results = try managedObjectContext.fetch(requestForGroups) as! [Group]
if results.count > 0
print(results.first)
var group: Group!
group = results.first
for users in group.existingUsers?.allObjects as! [Contact]
print(users)
for users in group.nonExistingUsers?.allObjects as! [Contact]
print(users)
catch let error as NSError
print("Error: \(error) " +
"description \(error.localizedDescription)")
当我尝试打印Group
对象时,出现以下关系错误
Optional(<Foodvite.Group: 0x1706801e0> (entity: Group; id: 0xd0000000018c0000 <x-coredata://E4C6CB69-7192-435C-9E2A-534FCFC563F5/Group/p99> ; data:
existingUsers = "<relationship fault: 0x17063b620 'existingUsers'>";
groupCategory = nil;
groupIconUrl = nil;
groupId = "8ba3e576-edf7-41fa-abd9-df80c4c693f2";
groupName = Friends;
groupOwnerId = "7fa49a4e-2cbf-4c77-8868-bc97ad89881b";
nonExistingUsers = "<relationship fault: 0x17063b600 'nonExistingUsers'>";
))
有人可以建议一种访问existingUsers
和nonExistingUsers
数据的方法吗?
【问题讨论】:
试试print(existingUsers!.first?.<#some property#>)
existingUsers
的类型为 NSSet
。它没有first
属性
公平点,但是 NSSet 的 allObjects
属性返回 Array
【参考方案1】:
这是正确的,因为默认情况下 Coredata 关系是延迟加载的。
这里是 Apple documentation。
托管对象通常表示保存在持久存储中的数据。 在某些情况下,托管对象可能是错误的——一个对象 尚未从外部数据存储加载属性值。 故障减少了您的应用程序消耗的内存量。
要访问existingUsers
和nonExistingUsers
数据,您需要明确询问(如果它们不是数组):
print(group!.existingUsers.<attributeName>)
print(group!.nonExistingUsers.<attributeName>)
如果你的关系是数组:
if let first = group?.existingUsers.first
print(first.<attributeName>)
阅读this 以获得更好的理解。
【讨论】:
我仍然遇到同样的故障错误。您能否建议另一种访问数据的方法? @Aark:你什么时候得到故障错误?在控制台中处于调试模式时?还是打印(results.first)? 我收到了Print(results.first)
和Print(group!.existingUsers)
的故障错误。这是在尝试打印 group.existingUsers
Optional(Relationship 'existingUsers' fault on managed object (0x17068e060) existingUsers
的类型为 NSSet
。它没有first
属性【参考方案2】:
错误不是错误。这是一个性能考虑,除非您确实需要它,否则不会加载来自持久存储的数据。对于具有表示与潜在 数千 个其他实体的一对多关系的属性的获取对象尤其如此。如果您甚至不打算使用它们,那么在内存中加载数千个其他对象是很愚蠢的。
在您的情况下,existingUsers
和 nonExistingUsers
可能都是 NSSet。您可以像这样访问其中的元素:
//assuming "group" is an NSManagedObject
for user in group.existingUsers!
user.property = someValue
if user.otherProperty == ...
在访问existingUsers
集合中的每个user
时,NSManagedObjectContext 将使用从持久存储中检索到的值自动填充对象的属性。简而言之,每个user
的属性的预期值将在您访问或分配它们时正确返回/设置。
【讨论】:
以上是关于访问核心数据中的子对象时出现关系错误的主要内容,如果未能解决你的问题,请参考以下文章