In a cocoa application that I’m writing, I want to create several different kinds of “subclasses” of NSMutableDictionary. I put that word in quotes because I know that the recommended way to add methods to classes such as NSMutableDictionary is to use categories.
However, this is creating a confusing situation for me.
I want each category of NSMutableDictionary to implement a “run” method that does different things, depending on which “subclass” I’m referencing. For example, let’s say I have the following 3 categories:
NSMutableDictionary+Category0
NSMutableDictionary+Category1
NSMutableDictionary+Category2
In each one, I want a “run” method that does, for example, the following:
In category 0 …
-(void)run {
NSLog(@"I'm running in NSMutableDictionary+Category0");
}
In category 1 …
-(void)run {
NSLog(@"I'm running in NSMutableDictionary+Category1");
}
In category 2 …
-(void)run {
NSLog(@"I'm running in NSMutableDictionary+Category2");
}
With these categories applied, I want to create an NSArray called, say, “myObjects” which contains a random mixture of the Category 0, Category 1, and Category 2 objects. Then, I want to do the following:
for (NSMutableDictionary* dict in myObjects) {
[dict run];
}
… and have each of the category-specific “run” methods to be invoked.
Unless I’m doing something wrong, I can’t get this to work properly, because each category attempts to add a “run” method to NSMutableDictionary, and only one of those will be called.
Is what I’m trying to do even possible? If so, could someone point me to the appropriate docs?
Thanks in advance.
Thanks to Sean and Caleb. I was afraid that I wouldn’t be able to do this, for the reasons you outlined, but I thought I’d ask anyway, in case I was missing some knowledge about Objective C or cocoa that might help me.
I need the “parent” class to be an NSMutableDictionary for various application-specific reasons, so I will manage this as follows …
I’ll create a category that adds a single “run” method to NSMutableDictionary. I’ll use a special key in that dictionary to hold the instance of a new “MyRunnable” class with its own “run” method. I’ll subclass this MyRunnable class for all the various “run” implementations I desire, and then I’ll instantiate the appropriate subclass and put it in the NSMutableDictionary with this special key. Then, in the NSMutableDictionary’s “run” method, I’ll just reference the instance of “MyRunnable” via the special key and invoke its own “run” method.
This is another form of containment which allows my top-level class to still be an NSMutableDictionary.
Thanks again.
No matter how many categories you have on a given class, there’s still only the one class. There’s no way to use one category in one place and a different one, omitting the first, in another spot in the same project. If you add the same method to a class in three different categories, the method that will be used is one added by the last category. However, the order in which categories will be added is not defined, so you have no way of knowing which method you’ll get.
Instead of using categories here, you should either: 1) create various subclasses of NSMutableDictionary, or 2) create a common base class that contains a mutable dictionary, and then subclass that as necessary. There’s a section on the NSMutableDictionary reference page that reads: