核心数据:访问属性的两种不同方式,只有一种有效
对于以下代码,在下面的两行注释中,只有第一行有效。
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*'
For the following code, of the two comment preceded lines below, only the first works.
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]];
The second returns and error
request for member 'value' in 'Event', which is of non-class type 'NSManagedObject*'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在开始之前,需要指出的是,在使用 Objective-C 编写代码时应遵循一些约定。类名应以大写字母开头:
Event
、NSManagedObject
、MKMapView
。变量应以小写字母开头:event
、currentUser
、myMapView
。现在,解决你的问题。
[Event setValue:foo forKey:value]
和Event.value=foo
(sic) 不同,除非变量值是包含以下内容的 NSString字符串值
。 (即NSString *value = @"value"
) 更清楚地说,foo.bar=baz
相当于[foo setValue:baz forKey:@" bar"]
不是[foo setValue:baz forKey:bar]
。Before we begin, it is important to point out that there are conventions that should be followed when writing code in Objective-C. Class names should start with a capital letter:
Event
,NSManagedObject
,MKMapView
. Variables should start with a lowercase letter:event
,currentUser
,myMapView
.Now, to your problem.
[Event setValue:foo forKey:value]
andEvent.value=foo
(sic) are not the same, except in the case where the variable value is an NSString containing the stringvalue
. (i.e.,NSString *value = @"value"
) Put more clearly,foo.bar=baz
is equivalent to[foo setValue:baz forKey:@"bar"]
not[foo setValue:baz forKey:bar]
.您看到的问题是由 NSManagedObject 类称为关联存储的行为引起的。
关联存储基本上将任何通用 NSManagedObject 转换为字典,其键是分配给它的实体的属性名称。您可以像字典或任何其他键值兼容类一样设置和访问键的值。因此,当您使用像这样的通用托管对象时:
...您将获得一个通用 NSManagedObject 实例,其中包含数据模型中定义的
str
实体的键。因此,当您可以使用键值编码将值存储在通用 NSManagedObject 实例中时:或者更清楚地类似于:
但是,点表示法有所不同。当您调用
Event.anAttributeName
时,您正在调用 NSManagedObject 的自定义子类中的方法。为了使其工作,您必须生成一个名为Event
的自定义子类,并将其分配给数据模型中的Event
实体。当您使用点表示法时,您正在调用一个如下所示的方法:
您可以自己编写该方法或使用 @dynamic 编译器指令来执行此操作,但无论哪种方式,您都必须拥有该方法。没有方法,没有点符号。
当您刚刚学习 Core Data 时,最好使用通用 NSManagedObjects 和 setValue:forKey: ,然后转向自定义 NSManagedObject 子类。
The problem you are seeing is caused by a behavior of the NSManagedObject class called associative storage.
Associative storage basically turns any generic NSManagedObject into a dictionary whose keys are the names of the property of the entity assigned to it. You set and access the values for the keys just like you would for a dictionary or any other key-value compliant class. So when you use a generic managed object like this:
... you get a generic NSManagedObject instance with the keys of the
str
entity as defined in the data model. So, when you can use key-value coding to store the value in the generic NSManagedObject instance:or more clearly something like:
However, dot notation is something different. When you call
Event.anAttributeName
you are calling a method within a custom subclass of NSManagedObject. In order for this to work, you must generate a custom subclass with the nameEvent
and assign it to theEvent
entity in the data model.When you use dot notation you are calling a method that looks something like this:
You can write the method yourself or use the
@dynamic
compiler directive to do it for but either way, you must have the method. No method, no dot notation.When you are just learning Core Data it is best to use generic NSManagedObjects and
setValue:forKey:
the move on to custom NSManagedObject subclasses.