13

I'm attempting to write an ActiveRecord-esque bit of code in Obj-C, and encountered the following situation: I'm trying to create a static class variable in a base class that gets the inheriting class's name and converts into the table name with pluralization and some other formatting operations. I know that for an instance of a class that one can do something along the lines of the following:

tableName = [[[self class] description] stringToTableName];

However, this requires one to use self. Is it possible to do something along following lines?

tableName = [[[inheriting_class class] description] stringToTableName];

I'd just prefer to not recalculate the table name for each instance of inherited class objects. I'd also prefer to have this bit of code autogenerate the table name with ruby-style metaprogramming.

MrSmith42
  • 9,961
  • 6
  • 38
  • 49
iand675
  • 1,118
  • 1
  • 11
  • 23

2 Answers2

21

Just use [self class]! When you call a class method in Objective-C, self will indicate which class is calling. For example:

#import <Foundation/Foundation.h>
#import <stdio.h>

@interface A: NSObject
+ (void)foo;
@end

@implementation A
+ (void)foo {
  printf("%s called!", [[[self class] description] UTF8String]);
}
@end

@interface B: A @end
@implementation B @end

int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [A foo];
    [B foo];
    [pool release];
    return 0;
}

should print

A called!
B called!
Jesse Beder
  • 33,081
  • 21
  • 109
  • 146
  • 12
    +1, although you can just do `self` instead of `[self class]`. In a class method, `self` *is* the `Class`. – Dave DeLong Nov 11 '10 at 02:06
  • 1
    @Dave, true; I've always preferred writing `[self class]` to make it clear that I'm looking for a class. – Jesse Beder Nov 11 '10 at 02:14
  • In this scenario, how would you declare a variable in the foo method that could be either an A or B depending on which class calls it? something like: typeof(self) record = [[[self class] alloc] init];? Or is id a satisfactory way of doing it? – iand675 Nov 11 '10 at 02:21
  • 2
    @iand675, `id` is perfectly fine. The only reason you'd want to declare it as a specific type is for compile-time checking; but the type is determined at runtime, so there'd be no need for it anyways! – Jesse Beder Nov 11 '10 at 03:00
  • @iand675 Note the latest version of Clang in Xcode 5 now supports the instancetype keyword. It works just like id but provides type checking. See more info here: http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using-instancetype-instead-of-id – memmons Oct 14 '13 at 18:59
  • I don't believe you can use property syntax on `self` within a class method. At least it doesn't work for me. For example within a class method on NSManagedObject, you couldn't use `self.entity` ... but maybe `[self entity]` – Logicsaurus Rex Jan 09 '16 at 06:12
0

How about using NSStringFromClass() (and NSStringFromSelector() if desired)?

NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
NSGod
  • 22,699
  • 3
  • 58
  • 66