找到Class方法的Selector

Nic*_*zol 1 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
Run Code Online (Sandbox Code Playgroud)

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

有没有想过找到我的班级方法?

Reg*_*ent 5

而不是打电话

NSString* result =  [self performSelector:NSSelectorFromString(method) withObject:json];
Run Code Online (Sandbox Code Playgroud)

你需要打电话

NSString* result =  [[self class] performSelector:NSSelectorFromString(method) withObject:json];
Run Code Online (Sandbox Code Playgroud)

对于类方法.

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

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

请参阅此处-class方法文档.


顺便说一句,您应该将方法调用包装到条件块中,以防止调用缺少方法导致的异常.

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

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

考虑一个类的情况,该类调用Foo实现一个方便的方法来返回自己的自动释放的实例(通过:)调用Foo *newFoo = [Foo foo];:

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

+ (id)foo {
    return [[[Foo alloc] init] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

这是正确的方法:

+ (id)foo {
    return [[[self alloc] init] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

因为第一个会导致子类中的多态性问题(例如一个被调用的子类FooBar,它应该显然是[FooBar alloc] …,不是[Foo alloc] ….幸运的是[[self class] alloc]动态地解决了这个问题).虽然这显然不是彻底解释这个问题的正确场所(可能会说是偏离主题的),但对于imho来说,当然值得注意/警告.