views:

493

answers:

2

I'd like to add additional behavior to a class derives from NSManagedObject and there are 4 distinct (for now) groups of behaviors. I don't need my decorator class to be persisted with CoreData -- it's purely for adding run-time behavior.

However, if I try to apply the standard Decorator pattern, I can't call '[super init]', which makes sense because you need to insert the new object into the ManageObjectContext. But I thought you'd want to invoke [super init] within WindowClassScrollDecorator's init and likewise, later 'dealloc' so everything gets initialized & cleaned up correctly.

I'm inheriting from 'MyWindowClass' class because I don't want my client classes to know the subtype but depending on the decorator used, the behavior will be different.

So what's a good way to approach this?

@interface MyWindowClass :  NSManagedObject  
{
}
@end

@interface WindowClassScrollDecorator: MyWindowClass
{
   MyWindowClass    *decoratedClass;
}

- (id)initWithMyWindowClass:(MyWindowClass *)aWindowClass;

@end

@implementation WindowClassScrollDecorator

- (id)initWithMyWindowClass:(MyWindowClass *)aWindowClass
{
    // Calling [super init] elicits the following error:
    // Failed to call designated initializer on NSManagedObject class 'ModelClassScrollDecorator' 
    if (self = [super init]) 
    {
        // do some initialization work here
        self.decoratedClass = aWindowClass;
    }
}

@end
A: 

The question you have here seems to not be CoreData specific but OO design.

You shouldn't be inheriting NSManagedObject if it is not a NSManagedObject.

You should make MyWindowClass either be a protocol, or a class which has a NSManagedObject.

groundhog
I need 'MyWindowClass' to be an NSManagedObject class and I need to apply one of four different types of behavior on this class at run time. What I'm then asking is, how do you apply different run-time behavior? If I use protocols, I would then have 4 different protocols but there still needs to be an intermediate class that applies the specific protocol. Or this something that can be annotated in the xcdatamodel class?
Alexi Groove
Again, I would say it should be a class that has a NSManagedObject, not is a NSManagedObject. If the decorator is not one, then it shouldn't inherit that class (all the way down the class hierarchy).What you are essentially saying here is that you want some of the descendants to be like a NSManagedObject and others to not. That means those descendants should behave that way not the base class.If you used a protocol, you would have one protocol and four implementations of that protocol. The ones that are NSManagedObjects would inherit that class.
groundhog
+1  A: 

The lifecycle of NSManagedObjects is a bit different from that of other objects; specifically, the object may turn into a fault (essentially a shell object without any of its properties set) without being deallocated. You should be sure to be aware of these events, so you may want to look at the NSManagedObject Class Reference - Subclassing Notes document. Specifically, you may want to look into awakeFromInsert:, awakeFromFetch:, and (will|did)TurnIntoFault.

To address your immediate issue, an NSManagedObject cannot be created without an NSManagedObjectContext to live in. Thus, to initialize a managed object, you must call its designated initializer:

initWithEntity:insertIntoManagedObjectContext:

Your init method needs to call that method on the superclass or else your NSManagedObject won't work.

BJ Homer