Phil Mitchell
Phil Mitchell

Reputation: 699

Call super within NSObject method but not on NSObject

I have a category on NSObject that defines a method with code like:

- (NSMutableDictionary *)myMethod
{
    NSMutableDictionary *myDict;
    if ([self isMemberOfClass:[NSObject class]]) {
        myDict = [NSMutableDictionary dictionary];        
    }
    else {
        myDict = [super myMethod];        
    }
    // DO STUFF HERE WITH myDict ...
    return myDict;
}    

It fails with NSObject cannot use super because it is a root class.

I can fix this by making it a base class rather than a category and having all my subclasses inherit from that instead of from NSObject, but that seems a bit lame. [Actually, this is wrong. The compiler won't let me call super from the base class implementation, either -- but see gabriel_101's workaround, below.] Is there any way around this?

Upvotes: 0

Views: 398

Answers (3)

Ken Thomases
Ken Thomases

Reputation: 90531

Sending a message to super is just a way to send that message to self but telling the runtime to start the search for the implementation in a different place. It makes no sense in a category that adds a new method. There's one and only one implementation of that method. So, the search can only have one of two results: it finds that one implementation or it finds nothing. Since you're already running the one implementation, the best an adjusted search could do is find nothing.

You have also left out whatever DO STUFF HERE would be. From what you've said in comments, I suspect it involved a misguided use of [self class]. [self class] will always have the same result for a given object. No amount of messaging to super will cause that to somehow return a superclass.

If you want to call class_copyPropertyList() with the chain of classes, then you must do something similar to what hypercrypt has suggested: iterate over the class chain yourself.

Upvotes: 1

gabriel_101
gabriel_101

Reputation: 808

In one of your comments you are saying that you are implementing a serialiser, hence it will be a good idea to look at NSCoding and NSKeyed​Archiver. You can find an example of how to use these here.

However if the above is not suitable for your problem I will suggest the following.

As NSObject is the root class, it does not have any state to save. Hence you could implement an empty myMethod in your category to NSObject, and you could override it in subclasses which need to store state. In these subclasses it will be ok to call [super myMethod] since it is declared in your NSObject category.

Upvotes: 0

hypercrypt
hypercrypt

Reputation: 15376

I would suggest doing something like this:

NSMutableDictionary *myDict = [NSMutableDictionary dictionary];
Class currentClass = [self class];
while (currentClass != [NSObject class])
{
    // Add stuff to myDict using currentClass
    currentClass = [currentClass superClass];
}

Upvotes: 1

Related Questions