找到Class方法的Selector

时间:2012-06-06 14:53:23

标签: objective-c

我是Objective C中的新手,虽然我有一些Java反射的背景。

在这里,我有一个经典的类方法 findAll ,可以从数据库中找到所有域对象。 Univers 类直接继承自 DomainObject

@interface DomainObject : NSObject

  - (NSString *) execute : (NSString*) method  withJson:(NSString*)json;
  + (NSString*)findAll: (NSString*)json;

@end

@implementation DomainObject

  - (NSString *) execute: (NSString*) method  withJson:(NSString*)json{

      method = [NSString stringWithFormat:@"%@%@", method, @":"]; 
      //method is 'findAll:'
      NSString* result =  [ self performSelector: 
          NSSelectorFromString(method) withObject:json];// Error here
      return result;    
  }
@end

当findAll不是类方法(即-findAll声明)时代码工作,但现在我有错误:NSInvalidArgumentException - [Univers findAll:] 很明显,运行时正在寻找实例方法。

有什么想法找到我的班级方法吗?

1 个答案:

答案 0 :(得分:5)

而不是打电话

NSString* result =  [self performSelector:NSSelectorFromString(method) withObject:json];

你需要打电话

NSString* result =  [[self class] performSelector:NSSelectorFromString(method) withObject:json];

用于类方法。

毕竟它是对象实例的类,它应该调用方法,而不是实例本身。

简短说明:NSObject实现- (Class)class;(不要误认为具有类似效果的+ (Class)classNSObject也实现了!),它会返回你的Class对象实例对象。请记住,除了普通的实例对象之外,在Objective-C中,类也是实际的对象:类型为Class的对象,即(与idNSObject,...)

请参阅-class方法here的文档。


不过,您应该将方法调用包装到条件块中,以防止调用缺少方法导致的异常。

SEL selector = NSSelectorFromString(method);
if ([[self class] respondsToSelector:selector]) {
    NSString* result =  [[self class] performSelector:selector withObject:json];
}

一般来说,Objective-C中的一个常见模式是通过[object class]接收类对象来调用对象的类方法。

考虑这个名为Foo的类的情况,它实现了一个方便的方法,用于返回自身的自动释放实例(通过:Foo *newFoo = [Foo foo];调用):

虽然可以实现这样的方法(毕竟我们知道对象的类名,对吧?):

+ (id)foo {
    return [[[Foo alloc] init] autorelease];
}

正确的方法是:

+ (id)foo {
    return [[[self alloc] init] autorelease];
}

因为第一个会导致子类中的多态性问题(例如一个名为FooBar的子类,它应该显然是[FooBar alloc] …,而不是[Foo alloc] …。幸运的是{{1} }动态解决这个问题。 虽然这显然不是彻底解释这个问题的正确场所(可能是人们可能会说的非常偏离),但是当然值得注意/警告,imho。