简体   繁体   中英

Initializing a subclass of an NSManagedObject's subclass

I have this NSManagedObject subclass generated from my Core Data data model:

@interface Customer : NSManagedObject
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSString * firstName;
@property (nonatomic, retain) NSString * familyName;
@end

The logic of my app has led me to define a subclass of this Customer class to extend its properties and provide some methods and keep them separated from the class generated from my data model:

@interface ExtCustomer : Customer
@property (nonatomic, retain) NSNumber *modificationDate;
+ (ExtCustomer *)parseJsonData:(NSData *)jsonData;
@end

I don't need to persist this modificationDate property, and what I want is to use the ExtCustomer objects throughout the app instead of Customer objects, but only save the Customer attributes by means of Core Data when needed.

I tried to instantiate ExtCustomer calling init , but this seems to be not possible since it inherits from NSManagedObject , so I tried to do this:

+ (ExtCustomer *)createExtCustomerInContext:(NSManagedObjectContext *)context
{
  NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Customer" inManagedObjectContext:context];
  ExtCustomer *customer = [[ExtCustomer alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context];

  [customer setFamilyName:@""];
  [customer setFirstName:@""];

  return customer;
}

But I see that, even if I cast the object ( return (ExtCustomer *)customer; ), what I actually get is a Customer object. Since I have not defined the ExtCustomer entity in my data model, I guess I can only get the NSEntityDescription of Customer . How could I solve this?

Thanks in advance

Unfortunately your way is not thread safe. Even if you extend the managedObject with something it is still managedObject. You should not keep the managedobjects through the app. basically you have to fetch from the core every time when you want to use Customer/ExtCustomer values or use fetchedResultConnroller to be in sync with the core.

The easiest solution is to add modificationDate to the core and keep it there.

Edited:

If you dont want to touch core data then you can create ExtCustomer extends NSObject. Add the same fields as in Customer + new one and keep them through the app. But in this case you have to sync the core Customer objects and your array of ExtCusomers every time. not a good way to do it but probably ok for your solution

BTDT and I cannot recommend doing it.

When you have edited your model and ask xcode to generate the class files, then xcode will overwrite any changes (and any code extensions) in that model class file. I did try to split model class definition and my model logic by extending the model class in various ways but as a result I found lots of problems at later stages in the app.

So basically what you want to do is to not let xcode recreate your class files. After you have made changes to the model you want to manually update your model files. An update to the class file should only be needed when the type or the name of an attribute changes.

This procedure does need a bit of discipline but is much easier to maintain and administer than any category or extensions of the model class.

Further I recommend to keep as much logic outside your model class. It is tempting to add logic into the model class to react to attribute values (or changes). But when evaluating this approach consider that your managedObject is rather short lived. Don't pass it around inside your app. The managedObject can be turned into a fault and your logic wont be reachable anymore.

Consider moving logic into a separate class the does not inherit form NSManagedObject. Copy the attributes needed for a particular task across and perform the required logic inside that separate class. That class wont fault on you and you'll have more liberties with the contexts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM