对于以下代码,在下面两行之前的两个注释中,只有第一个有效。
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*'
答案 0 :(得分:5)
在开始之前,重要的是要指出在Objective-C中编写代码时应遵循的约定。班级名称应以大写字母开头:Event
,NSManagedObject
,MKMapView
。变量应以小写字母开头:event
,currentUser
,myMapView
。
现在,你的问题。 [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子类。