27

Is there a way to call a class method from another method within the same class?

For example:

+classMethodA{
}

+classMethodB{
    //I would like to call classMethodA here
}
jscs
  • 63,694
  • 13
  • 151
  • 195
prostock
  • 9,327
  • 19
  • 70
  • 118

4 Answers4

65

In a class method, self refers to the class being messaged. So from within another class method (say classMethodB), use:

+ (void)classMethodB
{
    // ...
    [self classMethodA];
    // ...
}

From within an instance method (say instanceMethodB), use:

- (void)instanceMethodB
{
    // ...
    [[self class] classMethodA];
    // ...
}

Note that neither presumes which class you are messaging. The actual class may be a subclass.

Jon Reid
  • 20,545
  • 2
  • 64
  • 95
  • 1
    You switched up your terminology. `[self foo]` for instance methods, `[MyClass bar]` for class methods. – inspector-g Apr 12 '12 at 15:55
  • 8
    Nope. The meaning of `self` depends on what you're messaging. If you message a class, `self` is the class. If you message an instance, `self` is the instance. I explain the importance of messaging self for class methods in http://qualitycoding.org/factory-method/ – Jon Reid Apr 16 '12 at 01:09
  • Agreed, what you're saying in your comment is true, but the terminology in your answer is literally backwards. Using `[self class]` in an instance method doesn't make much sense, but it makes complete sense in a class method. Remember that instance methods begin with `-`, class methods begin with `+`, and using `self` to refer to an instance of an object has syntactic meaning but using `[self class]` to refer to an instance of an object makes no sense syntactically. `[self class]` implicates reference to an object that describes the class, and not an instance of the class. – inspector-g Apr 16 '12 at 04:06
  • @inspectorg, I guess I'm not understanding you. Our context is the question, how to invoke a class method. If you want to invoke a class method from an instance method (my second example), I first invoke `[self class]` to get the object's actual class, which may or may not be `MyClass`. – Jon Reid Apr 16 '12 at 05:14
  • 1
    I see what you're saying now, but the wording of your answer makes it unclear so you may want to edit it. You're saying that e.g. *inside* `classMethodB` of `MyClass` you want to call `classMethodA` of `MyClass`, you use `[self classMethodA]`; however, *inside* `instanceMethodB` of `MyClass` you want to call `classMethodA` of `MyClass`, you use `[[self class] classMethodA]`. This is correct! Your wording and simple examples suggests that one should use `self` to call class methods and `[self class]` to call instance methods, the latter of which is wrong (and what I thought you were saying). – inspector-g Apr 16 '12 at 05:27
  • +1 Yep, totally unambiguous now, thanks :) Now if only your answer was accepted, but unfortunately this question is over 6 months old... – inspector-g Apr 16 '12 at 19:19
8

Should be as simple as:

[MyClass classMethodA];

If that's not working, make sure you have the method signature defined in the class's interface. (Usually in a .h file)

Tom Jefferys
  • 13,090
  • 2
  • 35
  • 36
  • 1
    That is one way to do it; however, that will not respect sub-classing. In most cases it's probably wiser to use [self classMethodA]. As I understand in a class method "self" would be the class object (because class methods are instance methods of a class). So MyClass's method would be called but not MyClassSubclass's classMethodA – csga5000 Jan 07 '16 at 04:12
  • Also note that he said in the question "within the same class" – csga5000 Jan 07 '16 at 04:14
4

In objective C 'self' is used to call other methods within the same class.

So you just need to write

+classMethodB{
    [self classMethodA];
}
Tim
  • 14,447
  • 6
  • 40
  • 63
Indra Adam
  • 269
  • 3
  • 8
  • 1
    `self` is only proper for instance methods, but the question suggests he is talking about class methods (with the `+` sign before the method name) – inspector-g Apr 12 '12 at 15:56
3

Sure.

Say you have these methods defined:

@interface MDPerson : NSObject {
    NSString *firstName;
    NSString *lastName;

}

+ (id)person;
+ (id)personWithFirstName:(NSString *)aFirst lastName:(NSString *)aLast;
- (id)initWithFirstName:(NSString *)aFirst lastName:(NSString *)aLast;


@property (copy) NSString *firstName;
@property (copy) NSString *lastName;

@end

The first 2 class methods could be implemented as follows:

+ (id)person {
   return [[self class] personWithFirstName:@"John" lastName:@"Doe"];
}

+ (id)personWithFirstName:(NSString *)aFirst lastName:(NSString *)aLast {
    return [[[[self class] alloc] initWithFirstName:aFirst lastName:aLast]
                                                      autorelease];
}
NSGod
  • 22,699
  • 3
  • 58
  • 66