PDA

View Full Version : managed object class???




liptonlover
Jun 20, 2008, 09:12 AM
I'm working through the slightly outdated core data tutorial in Xcode,
(NSPersistentDocument Core Data Tutorial: The Employee Class - Developer Documentation)
and it's asking me to select a managed object class that is supposed to have these special options. I already know from a previous screenshot that this document hasn't been updated since the iphone SDK's, my select file interface layout is different. But apparently they also took out managed object classes, so I don't know what to do. I looked everywhere... Anyone know either how to make one, or how to get around it?



Krevnik
Jun 20, 2008, 10:47 AM
A managed object class is an object you write that subclasses from NSManagedObject. Usually once you create this subclass, you need to go into your Core Data object model and tell it the name of this class before it will use it.

liptonlover
Jun 20, 2008, 12:27 PM
I know how to subclass in the actual files, but the document says that you create one from the start and set some options... but there is no managed object subclass option.

Eraserhead
Jun 20, 2008, 12:46 PM
I know how to subclass in the actual files, but the document says that you create one from the start and set some options... but there is no managed object subclass option.

To do a subclass you type the name of your class in the managed object model and create the subclass file in Xcode and change it to be a subclass of NSManagedObject, not NSObject.

e.g. change:

@interface MyClass : NSObject

to

@interface MyClass : NSManagedObject

I should note that it is perfectly possible to avoid subclassing NSManagedObject ever (my program, D&D Manager (http://www.erasersoft.com/) doesn't). But it is bad code to do it like that, as it doesn't check at compile time for any errors in the key-value stuff.

So this is a case of do what I say, not what I do :).

EDIT for clarity (in bold).

Krevnik
Jun 20, 2008, 01:09 PM
I think the point of confusion here is that the tutorial points to a file template that doesn't exist (at least not in 3.1, and I don't recall seeing it in 3.0).

So what you want to do is use the standard class file template, and change NSObject to NSManagedObject like Eraserhead says.

For someone who is new to Object-oriented Programming, Apple's tutorials aren't the best. You should really grab a book that covers Cocoa programming. There are a couple good ones covered in this forum.


I should note that it is perfectly possible to avoid subclassing NSManagedObject ever (my program, D&D Manager (http://www.erasersoft.com/) doesn't). But it is bad code to do it like that, as it doesn't check at compile time for any errors in the key-value stuff.

It also creates more work for the poor programmer trying to learn by not subclassing NSManagedObject. :)

I usually don't even subclass unless I need a custom set of methods on top of the basic validating properties. Complex behaviors and the like. So in one of my projects, I have 6-7 different entities, but I only ever subclass 2 as their own type for added behavior.

liptonlover
Jun 20, 2008, 01:18 PM
I subclassed manually in the header file... still got the errors.
I agree, apple does not have the best beginner documentation. But I'm past the complete noob level, I'm moving on to more advanced stuff. I was hesitant to use Apple documentation to learn core data but I wasn't having any luck anywhere else... and except for this problem, I've been learning a lot and am now putting core data to good use.

Krevnik
Jun 20, 2008, 01:25 PM
Okay, if you are getting errors, lets start with those.

You didn't mention those at all in the first post.

liptonlover
Jun 20, 2008, 01:51 PM
sorry I thought I did. Here's what the document says to put in:

- (NSString *)fullNameAndID {
return [NSString stringWithFormat:@"%@, %@, (%@)",
self.lastName, self.firstName, self.employeeID];
}
+ (NSSet *)keyPathsForValuesAffectingFullNameAndID {
return [NSSet setWithObjects:
@"lastName", @"firstName", @"employeeID", nil];
}

errors:
error: request for member 'lastName' in something not a structure or union
error: request for member 'firstName' in something not a structure or union
error: request for member 'employeeID' in something not a structure or union

I know my code is exactly like the documentation, I'm %100 sure. I had already known that my class wasn't exactly right, so I assumed that was the problem.

Eraserhead
Jun 20, 2008, 02:12 PM
For someone who is new to Object-oriented Programming, Apple's tutorials aren't the best. You should really grab a book that covers Cocoa programming. There are a couple good ones covered in this forum.

I agree. I think they just assume everyone has a copy of Aaron Hillegass' book.

It also creates more work for the poor programmer trying to learn by not subclassing NSManagedObject. :)

True, I still think the behaviour is desired for serious applications, though you can get away without do it :).

I know my code is exactly like the documentation, I'm %100 sure. I had already known that my class wasn't exactly right, so I assumed that was the problem.

Can you post all the code in your file?

Krevnik
Jun 20, 2008, 02:59 PM
sorry I thought I did. Here's what the document says to put in:

- (NSString *)fullNameAndID {
return [NSString stringWithFormat:@"%@, %@, (%@)",
self.lastName, self.firstName, self.employeeID];
}
+ (NSSet *)keyPathsForValuesAffectingFullNameAndID {
return [NSSet setWithObjects:
@"lastName", @"firstName", @"employeeID", nil];
}

errors:
error: request for member 'lastName' in something not a structure or union
error: request for member 'firstName' in something not a structure or union
error: request for member 'employeeID' in something not a structure or union

I know my code is exactly like the documentation, I'm %100 sure. I had already known that my class wasn't exactly right, so I assumed that was the problem.

Aha, I know this. You have no properties! :)

One thing I hit is that CoreData will not automagically give you properties. You still need to use KVC, and/or declare the properties in your interface for the class.

liptonlover
Jun 20, 2008, 05:45 PM
I do have a property line of code... exactly what the documentation says to do. I can't get to my project right now but when I can I will go over it to make sure I did it right... I may have forgotten the semi-colon.

Krevnik
Jun 20, 2008, 06:13 PM
errors:
error: request for member 'lastName' in something not a structure or union
error: request for member 'firstName' in something not a structure or union
error: request for member 'employeeID' in something not a structure or union


I think you would have gotten worse errors if you forgot a semi-colon. These three errors tell me that the properties are not getting defined correctly in the header file at all.

self.<blah> only works when you have a @property declaration.

liptonlover
Jun 21, 2008, 08:55 AM
here's my property line, the only one they told me to put in.

@property (nonatomic, readonly) NSString *fullNameAndID;


here's the xcode documentation for this particular area:


In the Employee class’s header file, add a declaration for property:
@property (nonatomic, readonly) NSString *fullNameAndID;

Note that this is the only modification that you need to make to the header file. In particular, there is no need to add any instance variables.

In the implementation file, implement the fullNameAndID method. It concatenates the first and last names and the employee ID, as illustrated in the example below.

- (NSString *)fullNameAndID
{
return [NSString stringWithFormat:@"%@, %@ (%@)",
self.lastName, self.firstName, self.employeeID];
}

Notice how you can invoke the custom accessors directly (here using the dot syntax) even though you haven't provided an implementation.

In the Employee class, implement keyPathsForValuesAffectingFullNameAndID as follows:

+ (NSSet *)keyPathsForValuesAffectingFullNameAndID
{
return [NSSet setWithObjects:
@"lastName", @"firstName", @"employeeID", nil];
}

In the nib file, change the contentValues binding for the pop-up menu. Set the model key path to fullNameAndID (the other values remain the same).

Krevnik
Jun 21, 2008, 09:25 AM
Again, the tutorial is leading you down the wrong path. And it isn't anything to do with Core Data, but Objective-C 2.0 functionality.

You declare this property:

fullNameAndID

You use these properties:

lastName
firstName
employeeID

They don't match up at all. See the problem?

liptonlover
Jun 21, 2008, 09:27 AM
its in the core data section though, and I do want to learn how to do this too. But about that... so Apple's own documentation is completely screwed then? :eek:

Krevnik
Jun 21, 2008, 11:48 AM
If it is in the data model file, it doesn't make it a property automatically.

You can use KVC to get at it without adding new code, but properties aren't exposed on /any/ object unless declared. CoreData doesn't magically get around this.

liptonlover
Jun 21, 2008, 02:04 PM
by doing this:
@property (nonatomic, readonly) NSString *lastName;
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *employeeID;

I got the app to run just fine. I get three notices but it does exactly what it's supposed to according to the documentation. Thanks for your help guys!

Krevnik
Jun 21, 2008, 04:21 PM
by doing this:
@property (nonatomic, readonly) NSString *lastName;
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *employeeID;

I got the app to run just fine. I get three notices but it does exactly what it's supposed to according to the documentation. Thanks for your help guys!

There should also be a way to get rid of the warnings as well, but I can't remember it off the top of my head at the moment. I normally use KVC rather than properties on CoreData subclasses.

liptonlover
Jun 21, 2008, 05:31 PM
I want to use properties until I learn more about kvc... I went through the chapter in cocoa programming for mac os x but I need to learn more and go through it again.

Krevnik
Jun 21, 2008, 10:38 PM
Realize that properties are KVC-friendly by default.

The reason why your code works is because the NSManagedObject class handles the key names you added the @property line for.

The warnings are because you haven't specified how the property is supposed to be implemented (like you normally do). You can use one of the menu commands to copy the interface and implementation code snippets to the clipboard from the data model.

Properties are actually a lot easier to understand when you know KVC first, since they build on top of KVC.