views:

312

answers:

2

Hi

I have some NSManagedObjects and I would like to write methods for sorting and comparing the properties on them.

My problem is that since Core Data defines the properties as @dynamic they can not be referenced at compile time. This means that decorating an NSManagedObject with methods like this:

- (NSComparisonResult) compareDateAndTime:(Event *) event {
    return [originDate compare:[event originDate]];
}

will result in the compiler not being able to locate a property called "originDate". The above method is called like this:

NSArray *events = [[NSArray alloc] 
      initWithArray:[unsortedEvents sortedArrayUsingSelector:@selector(compareDateAndTime:)]];

I could go with predicates or fetchedResultController, but I would like to build these as methods myself as I have an identical NSObjects for each NSManagedObject. This NSObject acts as a temp object that is passed around and populated before it's properties are set on the NSManagedObject that is then persisted. I also have some other functions, like specialized accessors, I would like to add to the NSManagedObject.

(1)Is there a general/best practice way of decorating NSManagedObjects with methods and functions (2)and have Xcode not overwrite them when "re-building" a class for an Entity?

Thank you for any help or "RTFM" given:)

+2  A: 

I re-generate the model classes for my entities fairly often, so I added support methods (including implementations of getters for transient properties) as "Support" categories on the model classes.

I don't ever have to modify the model class files and there is no way I could accidentally overwrite my additional methods.

For example, a "Place" entity might have a name string and latitude/longitude numbers. It also could have a transient property for the first letter of the name. This can be used as the section name key path for section index titles in a large table view.

Xcode will generate the class files for the "Place" entity like this:

Place.h:

#import <CoreData/CoreData.h>

@interface Place :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * placeName;
@property (nonatomic, retain) NSNumber * latitude;
@property (nonatomic, retain) NSNumber * longitude;

@end

Place.m:

#import "Place.h"

@implementation Place 

@dynamic placeName;
@dynamic latitude;
@dynamic longitude;

@end

I create a "Support" category on the "Place" class.

PlaceSupport.h:

@interface Place (Support)

- (NSString *)uppercaseFirstLetterOfName;
- (CLLocation*)location;

@end

and implement it in PlaceSupport.m

gerry3
Thank you very much Gerry!Is my face red... I could not get rid of the error from the compiler so I ended up deleting my ManagedObjects, re-build them, close and restart Xcode and suddenly there was no problem accessing the properties. (now I know why I couldn't find this on google or in my Objective C book, there was no problem).I really like the Category solution, Im not very experienced in Objective C and keep forgetting that subclassing is not always necessary. At least something good came from my question:)
RickiG
A: 

Can you use objectForKey:?

On the other hand, I haven't had a problem with using the properties directly in my code.

Frank Schmitt
You are right Frank, I simply ran into some strange Xcode behavior and didn't have the experience to spot there was no proplem:)
RickiG