Rymnel
Rymnel

Reputation: 4515

Subclass of custom class that needs to subclass NSManagedObject

So here's my dilemma. I'm dealing with legacy code and trying to simplify and reduce a huge amount of redundancy in the code base. Here's the crux of the matter. I'm trying to consolidate two very similar classes into a superclass/subclass relationship. One is a subclass of NSObject the other a subclass of NSManagedObject.

I have a class that contains only variables called InventoryItems.h. It is a subclass of NSObject.

@property (nonatomic, retain) NSString * desc;
@property (nonatomic, retain) NSString * locationInventoryId;
...

InventoryItems.m

@synthesize desc;
@synthesize locationInventoryId;
...

There is another class that is called FavoriteInventoryItems.h that is a subclass of NSManagedObject. It contains exactly the same variables as InventoryItems with one additional variable.

FavoriteInventoryItems.h

@property (nonatomic, strong) NSString * desc;
@property (nonatomic, strong) NSString * locationInventoryId;
@property (nonatomic, strong) NSString * dateAddedAsFav;
....

FavoriteInventoryItems.m

@dynamic desc;
@dynamic locationInventoryId;
@dynamic dateAddedAsFav;
...

I can successfully make things work by making InventoryItems a subclass of NSManagedObject and then making FavoriteInventoryItems a subclass of InventoryItems. It does work but I get a message indicating the following:

CoreData: error: Failed to call designated initializer on NSManagedObject class 'InventoryItems'

My solution assuredly is a hack that may have negative consequences.

There are multiple places where the code resembles something like the following:

if (InventoryItem)
    ...many lines of code here
else if(FavoriteInventoryItem)
    ...exact same code as above based on favorites

I'm not sure how else to consolidate both of these class into superclass/subclass relationship. Or is there a better way to handle this problem that doesn't involve inheritance? Any ideas?

Upvotes: 0

Views: 485

Answers (1)

Wain
Wain

Reputation: 119031

Try to use a protocol to specify what is common between the classes and allow the 'using' code to be generic to the protocol.

The specification of a protocol is the important part, the implementation already exists in the 2 classes you have. The specification would list the common methods (or properties) between the 2 classes. Then, in the duplicated code, instead of saying:

InventoryItem *item = ...

or

FavoriteInventoryItem *item = ...

You would say:

id < InventoryItem > item = ...

I'm duplicating names because I can't know what a better name is, but the protocol is defined as:

@protocol InventoryItem < NSObject >

@property (nonatomic, strong) NSString * desc;
@property (nonatomic, strong) NSString * locationInventoryId;

@end

Then the code using the protocol doesn't care about what the underlying class is, it just cares what the protocol offers:

item.desc = @"Teddies";
item.locationInventoryId = ...

Upvotes: 3

Related Questions