2010-11-11 35 views
13

Estoy intentando escribir un código de código ActiveRecord-esque en Obj-C, y encontré la siguiente situación: Estoy tratando de crear una variable de clase estática en una clase base que obtiene el nombre de la clase heredada y la convierte en nombre de tabla con pluralización y algunas otras operaciones de formateo. Sé que para una instancia de una clase que uno puede hacer algo en la línea de lo siguiente:¿Hay algo así como auto para los métodos de clase?

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

Sin embargo, esto requiere que se debe usar self. ¿Es posible hacer algo a lo largo de las siguientes líneas?

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

Prefiero no recalcular el nombre de la tabla para cada instancia de objetos de clase heredados. También preferiría que este código genere automáticamente el nombre de la tabla con la metaprogramación ruby-style.

Respuesta

21

Solo use [self class]! Cuando llame a un método de clase en Objective-C, self indicará qué clase está llamando. Por ejemplo:

#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; 
} 

debe imprimir

A called! 
B called! 
+12

+1, aunque puede hacer 'self' en lugar de' [self class] '. En un método de clase, 'self' * es * the' Class'. –

+1

@Dave, cierto; Siempre he preferido escribir '[self class]' para dejar en claro que estoy buscando una clase. –

+0

En este escenario, ¿cómo declararía una variable en el método foo que podría ser una A o una B dependiendo de qué clase lo llame? algo como: typeof (self) record = [[[self class] alloc] init] ;? ¿O es id una forma satisfactoria de hacerlo? – iand675

0

Cómo sobre el uso NSStringFromClass() (y NSStringFromSelector() si se desea)?

NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); 
Cuestiones relacionadas