0

有人可以向我解释为什么这不起作用:

CoreDataClass *classObject = (CoreDataClass *)[some method that returns a dictionary with exact KVC pairs that match CoreDataClass];

NSString *myString = classObject.stringProperty;

但这确实:

CoreDataClass *classObject = (CoreDataClass *)[some method that returns a dictionary with exact KVC pairs that match CoreDataClass];
NSString *myString = [classObject valueForKey:@"stringProperty"];

编辑:将字典转换为我的 NSManagedObjectClass CoreDataClass 以便我可以直接访问属性的最简单方法是什么?

4

2 回答 2

2

它不起作用,因为 KVC 合规性根本不是定义类或使它们可转换的东西——类层次结构的存在是有原因的,仅仅确保遵守某些方法并不能神奇地使某些东西成为完全不同类的实例。请记住,点访问器语法只是方法发送的糖,所以这两个是等价的:

  • classObject.stringProperty
  • [classObject stringProperty]

...而后者显然对 NSDictionary 的实例无效(即[[NSDictionary class] instancesRespondToSelector:@selector(stringProperty)]is NO)。

您的后一个示例之所以有效,是因为您的问题的前提是:如果某些东西对 key 是 KVC 兼容的stringProperty,并且您要求它为该 key 提供一个值,那么显然您会得到一些回报。此外, NSDictionary 和 CoreDataClass 都响应选择器-valueForKey:,因此消息发送实际上在运行时起作用。

将两者结合起来的最佳方式根本不是“强制转换”——它是在属性级别上对所涉及的数据进行的完全转换。您可能会考虑-initWith...在 CoreDataClass 上创建一个自定义方法,让您从字典中实例化其属性,或者找到一种方法让您的方法返回 CoreDataClass 的实际实例而不是 NSDictionary。

请注意,此解决方案可能与获取数据的“最简单”方式不同,后者有效地继续做您正在做和使用的事情-valueForKey:(尽管最好没有演员表,这是误导)。

于 2012-09-12T13:38:13.750 回答
1

转换对象似乎只起作用(从某种意义上说,你不会得到类型检查错误),因为它是对编译器的提示,但它实际上并没有改变指针指向的任何内容,所以你仍然指向一个NSDictionary。这是因为,归根结底,您实际上是将指针转换为指针,但告诉 Xcode 您可以向它发送一组不同的选择器。

对于 NSManagedObjects,从字典创建取决于一些事情,但推荐的方法是在您的自定义类上创建一个类方法,该方法将使用 NSEntityDescription 和您的 NSManagedObjectContext,并将字典中的属性设置为对象:

+(CoreDataClass *) coreDataObjectWithDictionary:(NSDictionary *) spec {
  CoreDataClass *myInstance = [NSEntityDescription insertNewObjectForEntityForName: @"CoreDataClass" inManagedObjectContext: [myMOCProvider sharedMOC];
  myInstance.someProp = [spec valueForKey:@"someProp"];
} 
于 2012-09-12T13:40:46.803 回答