Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Chirone

macrumors 6502
Original poster
Mar 2, 2009
279
0
NZ
i randomly found a tutorial in the xcode documentation to do with core data
it involves employees and departments

In the part where it creates the employee and gives it a unique id i'm rather confused as to how this was achieved...

the value of the popupbox comes from the returned string from -(NSString*)fullNameAndID
which is derived from lastName, firstName, and employeeID
lastName and firstName are declared a @property (retain) in the header file (what does that mean?) as NSStrings, and employee is the same but as an NSNumber

so when the program runs the popup box gives the lastName firstName + employeeID
but to make the employeeID unique this code was inserted
Code:
- (void)awakeFromInsert {
	static NSInteger tempID = 1;

	[super awakeFromInsert];
	self.primitiveEmployeeID = [NSNumber numberWithInteger:tempID++];
}
and primitiveEmployeeID was added to the header file as @property (retain) NSNumber

and when the program runs the employeeID is now unique...
how is that possible? employeeID is never touched... yet it gets incremented each time a new employee entity is added to the array controller

also, the tutorial says that this is not a great way of doing this.... what should the correct way of making sure an entity's property value is unique?
 
Chirone

The primitiveEmployeeID is set to the current tempID when the object is created - the primitiveEmployeeID instance variables never change once they have been set in the awakeFromInsert method. It's the tempID that gets increased in your code.

Note that tempID++ does the same as:
Code:
tempID = tempID + 1;

The tutorial suggests why the code is insufficient for production applications. The class variable tempID is set to 1 the first time the method is called after launching the application. As such, you would see duplication when your application saves and opens documents across launches. One solution would be to save the tempID using NSUserDefaults and restore the value when the application is re-opened. For a document-based application, you probably want to initialize the value somewhere in your NSPersistentDocument subclass. Where it is now, the ID would be incremented across documents. This may be desired, so where the initialization occurs depends on what you want.

For getting the currentID from NSUserDefaults.
- this should be done from the awakeFromInsert method or another method somewhere in your document subclass
- 0 is returned if the key has not yet been set in NSUserDefaults, so only set the tempID if currentID != 0
Code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger currentID = [defaults integerForKey:@"currentID"];
if (currentID != 0) tempID = currentID;

For setting the currentID to NSUserDefaults.
Code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:[NSNumber numberWithInteger:tempID]];

For making tempID available to other objects.
Code:
+ (NSInteger)sharedTempID {
  return tempID;
}

BTW: There is a book about Core Data available from Pragmatic Programmers in case you're interested. I just started reading it myself, so I can't say much about quality yet.

Kind regards

Luke
 
thanks Luke,
you're answer makes sense

but why is it that in the
Code:
- (NSString*)fullNameAndID {
	return [NSString stringWithFormat: @"%@, %@, (%@)",
			self.lastName, self.firstName, self.employeeID];
}
method the employeeID is what the primitiveEmployeeID is

i don't see at any point where employeeID = primitiveEmployeeID which is what i expected...
this new stuff is quite confusing :p

thanks again Luke
 
From Managed Object Accessor Methods in the Core Data Programming Guide:

Key-value coding access pattern
The access pattern key-value coding uses for managed objects is largely the same as that used for subclasses of NSObject—see valueForKey:. The difference is that, if after checking the normal resolutions valueForKey: would throw an unbound key exception, the key-value coding mechanism for NSManagedObject checks whether the key is a modeled property. If the key matches an entity's property, the mechanism looks first for an accessor method of the form primitiveKey, and if that is not found then looks for a value for key in the managed object's internal storage. If these fail, NSManagedObject throws an unbound key exception (just like valueForKey:).

Key-value coding is important to understand when doing any Cocoa Programming. Similar concepts exist in other environments, so the concept often gets taken for granted in tutorials. If you read the above paragraph carefully, you should get a general idea of what to watch out for. Bottom line: when you use an accessor method, the frameworks automatically look in various places based on convention.

Primitives were something I didn't understand immediately when I started working with Core Data. If you read about custom accessor methods, you'll see the difference in practice. Bottom line: when you use the regular accessor methods, observers are told that the accessor method has been called. With primitives, those notifications are not made. ** someone please correct me if I am mistaken **

If you want to understand KVO and KVC, ruby on rails is a great place to do so. I also find that ruby on rails helps if you are new to the model-view-controller convention.
 
one more thing about core data

is there a quick reference that will tell me what these things are in the datamodel and in code?

things like:

when adding a relationship there is the delete rule and cascade rule (i know the difference between them now but i only stumbled upon that randomly)
and things like @dynamic and Reg Ex in a string type (i assume that's a regular expression) and transient and indexed

i saw the glossary in the core data programming guide but it only had so much...
 
You may want to read the Core Data article on Cocoa Dev Central. You can find that here:
http://cocoadevcentral.com/articles/000086.php

As mentioned in my first post, there is a book about Core Data available from Pragmatic Programmers. It's still not complete, but you can get an early copy here:
http://pragprog.com/titles/mzcd/core-data

The programming guides included with Xcode are often the best place to learn. I usually try to read the guides before working with new frameworks. They typically provide enough information that you can learn the rest from the API documentation.

Good luck with everything
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.