Reputation: 1650
I have a collection of Objective-C classes that get sub-classed at a variety of different depths by a variety of different classes. Once the entire object is initialized (all of the sub-classes init functions have finished), I need to run an "Update Cache" method which then gets Overridden by the sub-classes as needed.
My Problem: With a variety of different inheritance depths to my class tree, there is no one place where I can put [self UpdateCache] and I can be sure that there is no sub-class that has not been initialized. The only possible solution would be to call [super init] after the initialization of each class so that the parent class is always called last. I want to avoid this as this goes against all guidelines of writing Objective-C. Is there any clean solution to this problem?
Here is an some example code:
@interface ClassA : NSObject
-(void)UpdateCache
@end
@interface ClassB : ClassA
-(void)UpdateCache
@end
@interface ClassC : ClassB
-(void)UpdateCache
@end
Now for the implementation we need to somehow get UpdateCahce to be called after we know all sub classes have initialized regardless of which class has been initialized
@implementation A
-(id)init
{
if(self = [super init])
{
// Placing [self UpdateCache] here would make it be called prior to
// B and C's complete init function from being called.
}
}
-(void)UpdateCache
{
}
@end
@implementation B
-(id)init
{
if(self = [super init])
{
// Placing [self UpdateCache] would result in UpdateChache not being
// called if you initialized an instance of Class A
}
}
-(void)UpdateCache
{
[super UpdateCache];
}
@end
@implementation C
-(id)init
{
if(self = [super init])
{
// Placing [self UpdateCache] would result in UpdateChache not
//being called if you initialized an instance of Class A or B
}
}
-(void)UpdateCache
{
[super UpdateCache];
}
@end
Upvotes: 2
Views: 194
Reputation: 5703
Do your sub-classes require unique init method signatures? (e.g. sub-class specific parameters required to initialize the object) If not, following a simple factory-like design pattern may work fine.
Example of what to add your parent/base class:
+(id)buildSelf {
YourParentClass* obj = [[[self alloc] init] autorelease];
if (obj) {
[obj updateCache];
}
return obj;
}
Add parameters to it, for all sub-classes to use, if needed.
Again, if your sub-classes need to support unique init method signatures then this won't work so well.
Upvotes: 1
Reputation: 489
Rather than updating the cache right after init, why not instead update it right before it is first used? Perhaps you can have an boolean instance variable cacheIsDirty
which you set to TRUE
in init. Then, your getter for the cache calls updateCache
first if the cache is dirty. Assuming that you're always using getters and never using the instance variable directly (which is good practice in Objective-C) clients shouldn't notice a difference.
Upvotes: 3
Reputation: 55573
Yes, I asked a similar question a while back...
You can add a 'hook' / 'proxy' to an instance of an object to override the -forwardInvocation:
selector and perform what you want. The original question is here, and my answer on it is the accepted one.
Upvotes: 0
Reputation: 3355
Declare a virtual method and call it when you need it....
and since this is objective c see Implement a pure virtual method in Objective-C
Upvotes: 0