Call instance method from class method

15,132

Solution 1

There is not a way to do this. It simply doesn't work with object-orientation.

Classes are kinds of things. That's it. They simply describe what that kind of thing does.

An example might be that you have a 'Dog' class. You would have instance methods that would define how a dog wags its tail or how it eats. You might have a class method to purchase a dog.

My pet dog Fido is an instance of class dog. I can send Fido messages, telling him to wag his tail and eat his food. I cannot, however, ask the class 'Dog' to wag its tail; whose tail would wag? Would it be Fido's, or would it be my neighbor's dog?

When you send a message to the class, you don't have a 'self' variable to work with. There's nothing that could tell itself to wag its own tail. Class messages are mostly used for creating instances of the class or getting at other general information.

Edit: To clarify, that last paragraph is an oversimplification. There is a 'self' variable in class methods as bbum describes - it's the computer's reference to the description of the class. That said, I don't think I've ever had an occasion to use 'self' in a class method.

Solution 2

If you want to call an instance method you need an instance to call the method on.

self is a reference to the instance that is being messaged. Thus self in a class method is the class and self in an instance method is an instance of the class.

So, naively, you might do:

+(id)barWithFoo:(NSFoo *) {
    [[[self alloc] init] foo]; //Raises compiler warning. 
}

-(void)foo {
//cool stuff
}

Of course, that'd leak memory in a non-GC application (since the instance isn't being released or autoreleased). Instead of explaining why, I will point you to the Objective-C intro documentation. It is some awesome stuff, covering both Objective-C and general object oriented programming patterns.

Solution 3

+ (MyClass *)getInstance
{
    static MyClass *classInstance;

    @synchronized(self)
    {
        if (!classInstance)
        {
            // This is never freed.  Is a singleton a leak?
            classInstance = [[[MyClass alloc] init] retain];
        }
    }

    return classInstance;
}

[[MyClass getInstance] instanceMethod];
Share:
15,132

Related videos on Youtube

Moot
Author by

Moot

Updated on April 15, 2022

Comments

  • Moot
    Moot about 2 years

    So I need to call some instance methods from class methods in Objective-C...

    Example :

    +(id)barWithFoo:(NSFoo *) {
    [self foo]; //Raises compiler warning. 
    }
    
    -(void)foo {
    //cool stuff
    }
    

    So my question; StackOverFlow is how do you do such things in Objective-C, I'm new kinda to OOP, so am I mad, or is there a way to do this?

    • B 7
      B 7 almost 8 years
      No, it doesn't answer to Moot's question. Moot wants to know if it is possible to call an instance method from inside a class method. No, we can't!! But you could use NSNotificationCenter, add an observer with a selector on your instance method, and postNotification from inside your class method
  • Moot
    Moot over 14 years
    This is rather revealing! Thanks so much!
  • Moot
    Moot over 14 years
    This is a good workaround Thanks!, although I do have to admit, this does go against object - orientation.
  • bbum
    bbum over 14 years
    No, it doesn't. A common pattern is to instantiate some object and then tell it to -startDoingSomethingUsefulAutomatically. Once started, the object may be left to its own devices for the rest of the app session.
  • bbum
    bbum over 14 years
    It also is not a workaround. You asked how to call an instance method from a class method. To do so requires an instance. End of story.