核心数据:访问属性的两种不同方式,只有一种工作方式

时间:2010-10-11 17:21:11

标签: iphone core-data key-value-coding nsmanagedobject

对于以下代码,在下面两行之前的两个注释中,只有第一个有效。

NSManagedObject * Event = [NSEntityDescription insertNewObjectForEntityForName:str inManagedObjectContext:app.managedObjectContext]; 
//Work but strange
[Event setValue:[NSNumber numberWithInt:buf4[v+h]] forKey:value]; 
 //Error
Event.value= [NSNumber numberWithInt:buf4[v+h]]; 

第二次返回错误

request for member 'value' in 'Event', which is of non-class type 'NSManagedObject*'

2 个答案:

答案 0 :(得分:5)

在开始之前,重要的是要指出在Objective-C中编写代码时应遵循的约定。班级名称应以大写字母开头:EventNSManagedObjectMKMapView。变量应以小写字母开头:eventcurrentUsermyMapView

现在,你的问题。 [Event setValue:foo forKey:value]Event.value=foo(sic)不相同,除非变量值是包含字符串value的NSString。 (即NSString *value = @"value")更清楚地说,foo.bar=baz相当于[foo setValue:baz forKey:@"bar"]而不是[foo setValue:baz forKey:bar]

答案 1 :(得分:3)

您看到的问题是由名为关联存储的NSManagedObject类的行为引起的。

关联存储基本上将任何通用NSManagedObject转换为字典,其字符串是分配给它的实体的属性的名称。您可以像设置字典或任何其他符合键值的类一样设置和访问键的值。因此,当您使用这样的通用托管对象时:

NSManagedObject * Event = [NSEntityDescription insertNewObjectForEntityForName:str inManagedObjectContext:app.managedObjectContext]; 

...您将获得一个通用NSManagedObject实例,其中包含数据模型中定义的str实体的键。因此,当您可以使用键值编码将值存储在通用NSManagedObject实例中时:

[Event setValue:[NSNumber numberWithInt:buf4[v+h]] forKey:value];

或更明显的类似:

[Event setValue:[NSNumber numberWithInt:buf4[v+h]] forKey:@"anAttributeName"];

然而,点符号是不同的。当您调用Event.anAttributeName时,您正在调用NSManagedObject的自定义子类中的方法。为此,您必须生成名为Event的自定义子类,并将其分配给数据模型中的Event实体。

使用点表示法时,您调用的方法如下所示:

-(void) setAnAttributeName:(NSNumber *) aNumber{
    //some boilerplate
    [self setPrimativeValue:aNumber forKey:@"anAttributeValue"];
    // some more boilerplate
}

您可以自己编写方法或使用@dynamic编译器指令来执行此操作,但无论如何,您必须拥有该方法。没有方法,没有点符号。

当您刚学习核心数据时,最好使用通用NSManagedObjects和setValue:forKey:继续自定义NSManagedObject子类。