views:

59

answers:

2

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*'
+4  A: 

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] and Event.value=foo (sic) are not the same, except in the case where the variable value is an NSString containing the string value. (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].

John Franklin
+1  A: 

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:

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

... 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:

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

or more clearly something like:

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

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 name Event and assign it to the Event entity in the data model.

When you use dot notation you are calling a method that looks something like this:

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

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.

TechZen