从 Core-Data 请求不同的 NSManagedObject 属性实例时返回啥类?
Posted
技术标签:
【中文标题】从 Core-Data 请求不同的 NSManagedObject 属性实例时返回啥类?【英文标题】:What class is returned when requesting distinct NSManagedObject property instances from Core-Data?从 Core-Data 请求不同的 NSManagedObject 属性实例时返回什么类? 【发布时间】:2013-11-07 15:59:51 【问题描述】:我有一个简单的情况,我有一个 CDPerson 类,它是 NSManagedObject 的子类。此类包含与 CDHair 类(也是 NSManagedObject 的子类)的一对一关系。 CDPerson 类的关系属性名为“hair”。
我想了解 ManagedObjectContext 中所有 CDPerson 实例实际使用的不同 CDHair 实例。
我正在获取一个不同的属性列表(这部分有效),
NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
fetchRequest.returnsDistinctResults = YES;
fetchRequest.propertiesToFetch = @[@"hair"];
fetchRequest.resultType =NSDictionaryResultType;
fetchRequest.predicate=[NSPredicate predicateWithFormat:@"hat=='no'"];
fetchRequest.returnsDistinctResults = YES;
NSArray* fetchResults = [context executeFetchRequest:fetchRequest error:&error];
fetchResults 在 NSArray 中符合预期。 fetchResults[0] 是预期的 NSDictionary。 fetchResults[0][@"hair"] 解决了一些问题,但我不知道它是什么。它的 po 描述是
0x8b7b120 <x-coredata://C7E53293-94C7-444D-8162-167B1D66A961/Hair/p33>
它似乎没有选择器。如果我将它转换为 CDHair 并尝试使用实例上的属性,例如 .color,我会收到“无法识别的选择器”错误。
CDTest[2865:70b] -[_NSObjectID_48_0 color]: unrecognized selector sent to instance 0x8ba8670
首先,我不知道 _NSObjectID_48_0 类是什么。 其次,我认为从 fetch 中检索到的属性将是 CDHair 的 CoreData 实例,但情况似乎并非如此。也不是 NSManagedObject。
我哪里出错了?
【问题讨论】:
你能贴出你的fetchRequest的所有代码吗 您确定您在 fetchRequest 中指定的实体名称是 "CDHair" 吗? “/Hair/p33”表示它是一个实体名称为“Hair”且ID为“p33”的对象 为了记录,当你明确要求NSDictionaryResultType
时,你不会得到任何NSManagedObject
s。这意味着您不会得到隐含的错误或任何其他对象图的细节。另一方面,字典是线程安全的,并且可以保证不会意外触发对后备存储的任何访问 - 如果您正在进行多线程存储访问,则可能必须等待锁定被释放。跨度>
谢谢大家。我看到我真正缺少的是 [context objectWithID:] 来获取实际对象。
@RyanG 发布了所有 fetchRequest 代码。
【参考方案1】:
既然你已经明确设置了
fetchRequest.resultType = NSDictionaryResultType;
获取请求返回一个字典,并表示与其他对象的关系
通过NSManagedObjectID
。您可以从“托管”中检索相应的对象
对象 id" 使用 objectWithID
或 existingObjectWithID
方法。例如:
NSManagedObjectID *mid = fetchResults[0][@"hair"];
CDHair *hair = (CDHair *)[context objectWithID:mid];
NSString *color = hair.color;
但将propertiesToFetch
设置为CDHair
的实际属性可能更容易
你感兴趣的,例如
fetchRequest.propertiesToFetch = @[@"hair.color"];
那么结果数组会是这样的
( “头发。颜色”=绿色; , “头发.颜色”=红色; )你可以像这样访问它
NSString *color = fetchResults[0][@"hair.color"];
【讨论】:
啊! [上下文 objectWithID:mid]! CoreData 有很多陷阱。谢谢! @SamuelRenkert:这就是为什么我也提到了 existingObjectWithID 以及避免对象 ID 的替代方法。不客气。【参考方案2】:您要求CDPerson
实体的关系属性。这只会导致返回的字典被这些人的相关CDHair
的objectID
填充。
结果字典中填充了与结果集的CDHair
元素(所有现有人员)相关的NSObjectID
对象。这就是为什么您不能直接使用这些对象来获取它们的属性的原因。您可以通过使用NSManagedObjectContext
的existingObjectWithID:error:
、objectWithID:
并将返回的ID 传递给它来获取实际对象。
如果您喜欢不同的 CDHair
正在使用的对象,您可以将您的请求更改为:
(假设逆向关系命名为persons
)
NSFetchRequest* req = [NSFetchRequest fetchRequestWithEntityName:@"CDHair"];
req.predicate = [NSPredicate predicateWithFormat:@"persons.@count != 0"];
这应该会为您提供所有不同的 CDHair
对象,这些对象正被您的商店中的 CDPerson
s 使用。
【讨论】:
酷。在我的测试中,我确实发现我得到了一个不同的 NSObjectID 列表,它反映了我期望的不同头发。我认为这是可行的,因为每个 CDHair 都有一个唯一的 ID,所有红发女郎共享同一个 CDHair 实例。我必须承认,我喜欢你对 fetch distinct 请求的实现,并且会转换为使用它,因为它会返回活动实例。 您对不同的结果是正确的,我已经编辑了我的答案以反映这一点【参考方案3】:你试过这样获取颜色属性吗?
NSArray* fetchResults = [moc executeFetchRequest:fetchRequest error:&error];
for (NSDictionary* hair in fetchResults)
NSLog(@"Hair Color is:", [hair objectForKey:@"color"]);
【讨论】:
以上是关于从 Core-Data 请求不同的 NSManagedObject 属性实例时返回啥类?的主要内容,如果未能解决你的问题,请参考以下文章
IOS/objective-c/core-data:如何从相关实体获取属性
如何在 Mac 和 iPhone 之间同步 Core-Data 应用程序?